LateInitializationError:字段“chatRoomsStream”尚未在 Flutter 中初始化

Posted

技术标签:

【中文标题】LateInitializationError:字段“chatRoomsStream”尚未在 Flutter 中初始化【英文标题】:LateInitializationError: Field 'chatRoomsStream' has not been initialized in Flutter 【发布时间】:2021-11-20 05:26:25 【问题描述】:

我正在使用 Firebase 在 Flutter 上构建一个 Messenger 应用,当我点击与其他用户聊天时 - 我在加载之前的消息之前收到此异常。

  ======== Exception caught by widgets library =======================================================
The following LateError was thrown building ChatRoom(dirty, state: _ChatRoomState#be2bb):
LateInitializationError: Field 'chatRoomsStream' has not been initialized.

The relevant error-causing widget was: 
  ChatRoom file:///D:/android/chat_app/lib/main.dart:47:55
When the exception was thrown, this was the stack: 
#0      _ChatRoomState.chatRoomsStream (package:chat_app/views/chatRoomsScreen.dart)
#1      _ChatRoomState.chatRoomList (package:chat_app/views/chatRoomsScreen.dart:29:15)
#2      _ChatRoomState.build (package:chat_app/views/chatRoomsScreen.dart:83:15)
#3      StatefulElement.build (package:flutter/src/widgets/framework.dart:4691:27)
#4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4574:15)
...
====================================================================================================

这是导致问题的 chatRoomsScreen.dart 页面,这是每次用户想要与其他用户聊天时加载的页面:

    import 'package:chat_app/helper/authenticate.dart';
import 'package:chat_app/helper/constants.dart';
import 'package:chat_app/helper/helperfunctions.dart';
import 'package:chat_app/services/auth.dart';
import 'package:chat_app/services/database.dart';
import 'package:chat_app/views/conversationScreen.dart';
import 'package:chat_app/views/search.dart';
import 'package:chat_app/views/signin.dart';
import 'package:chat_app/widgets/widgets.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class ChatRoom extends StatefulWidget 
  const ChatRoom(Key? key) : super(key: key);

  @override
  _ChatRoomState createState() => _ChatRoomState();


class _ChatRoomState extends State<ChatRoom> 

  AuthMethods authMethods = new AuthMethods();
  DatabaseMethods databaseMethods = new DatabaseMethods();

  late Stream<QuerySnapshot> chatRoomsStream;

  Widget chatRoomList() 
    return StreamBuilder(
      stream: chatRoomsStream,
      builder: (context, snapshot) 
        return snapshot.hasData ? ListView.builder(
          itemCount: (snapshot.data as QuerySnapshot).docs.length,
          itemBuilder: (context, index) 
            return ChatRoomsTile(
                (snapshot.data as QuerySnapshot).docs[index]["chatroomid"]
                    .toString().replaceAll("_", "")
                    .replaceAll(Constants.myName, ""),
                (snapshot.data as QuerySnapshot).docs[index]["chatroomid"]
            );
          ,
        ) : Container();
      ,
    );
  

  @override
  void initState() 
    getUserInfo();
    super.initState();
  

  getUserInfo() async 
    Constants.myName = (await HelperFunctions.getUserNameSharedPreference())!;
    databaseMethods.getChatRooms(Constants.myName).then((value) 
      setState(() 
        chatRoomsStream = value;
      );
    );
    setState(() 

    );
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
        appBar: AppBar(
              title: Image.asset("assets/images/logo.png", height: 50.0),

        actions: [
          GestureDetector(
            onTap: () 
              authMethods.signOut();
              Navigator.pushReplacement(context,
              MaterialPageRoute(builder: (context) => Authenticate()
              ));
            ,
            child: Container(
              padding: EdgeInsets.symmetric(horizontal: 16),
                child: Icon(Icons.exit_to_app)),
          ),
        ],),
        body: chatRoomList(),
        floatingActionButton: FloatingActionButton(
          onPressed: () 
            Navigator.pushReplacement(context, MaterialPageRoute(
              builder: (context) => SearchScreen()
            ));
          ,
          child: Icon(Icons.search),
        ),
    );
  


class ChatRoomsTile extends StatelessWidget 
  late final String userName;
  late final String chatRoomId;

  ChatRoomsTile(this.userName,this.chatRoomId);
  
  @override
  Widget build(BuildContext context) 
    return GestureDetector(
      onTap: () 
        Navigator.push(context, MaterialPageRoute(
          builder: (context) => ConversationScreen(chatRoomId: chatRoomId)
        ));
      ,
      child: Container(
        padding: EdgeInsets.symmetric(horizontal: 24, vertical: 20),
        child: Row(
          children: [
            Container(
              height: 40,
              width: 40,
              alignment: Alignment.center,
              decoration: BoxDecoration(
                  color: Colors.amber,
                  borderRadius: BorderRadius.circular(30)),

              child: Text(userName.substring(0, 1),
                  textAlign: TextAlign.center,
                  style: TextStyle(
                      color: Colors.white,
                      fontSize: 16,
                      fontFamily: 'OverpassRegular',
                      fontWeight: FontWeight.w300)),
            ),
              SizedBox(width: 12,),
              Text(userName, style: mediumTextStyle(),),
          ],
        ),
      ),
    );
  

chatRoomsStream 我做错了什么?我尽可能早地初始化它,对我来说,它已经完成了。也许你们中的一个人可以指出为什么每次加载此页面时我都会收到此异常 - 非常感谢您的帮助,谢谢。

【问题讨论】:

【参考方案1】:

为了您的好消息,使用late关键字意味着当您第一次使用它时,即时将被初始化。 喜欢:

late int value = 5;
late int value; // you got the error 

更多关于sound null safety

More about lazy initialization

注意:在你的情况下,你可以删除late,否则初始化它。

【讨论】:

【参考方案2】:

而不是late Stream&lt;QuerySnapshot&gt; chatRoomsStream;

使用Stream&lt;QuerySnapshot&gt;? chatRoomsStream;

当你打电话给chatRoomStream 称它为chatRoomStream! 这是零安全 know about null safety

【讨论】:

嘿,我按照你的要求做了,“Late Initilization”错误消失了,但现在它是“stream:chatRoomsStream!”上的“Null check operator used on a Null value”,这是我的 getChatRooms在 database.dart: getChatRooms(String userName) async return await FirebaseFirestore.instance .collection("ChatRoom") .where("users",arrayContains: userName) .snapshots();

以上是关于LateInitializationError:字段“chatRoomsStream”尚未在 Flutter 中初始化的主要内容,如果未能解决你的问题,请参考以下文章

LateInitializationError:字段“_userData@32329253”尚未初始化

LateInitializationError:字段尚未在 Flutter 中初始化

LateInitializationError:字段“chatRoomsStream”尚未在 Flutter 中初始化

如何解决 Flutter 中的 LateInitializationError?

LateInitializationError:字段“显示名称”尚未在 Flutter 共享首选项中初始化?

即使我在 initState 中初始化变量,Dart 也会抛出 LateInitializationError