Home > database >  LateInitializationError: Field 'chatRoomsStream' has not been initialized in Flutter
LateInitializationError: Field 'chatRoomsStream' has not been initialized in Flutter

Time:09-28

I'm building a Messenger app on Flutter using Firebase and when I click to chat with another user - I get this exception before the previous messages are loaded.

  ======== 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)
...
====================================================================================================

This is the chatRoomsScreen.dart page that is causing the issue, this is the page that is loaded every time a user wants to chat with another user:

    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(),),
          ],
        ),
      ),
    );
  }
}

What am I doing wrong with chatRoomsStream? I'm initializing it as early as I can and to me, it's done as it should be. Perhaps one of you can point out why I'm getting this exception every time this page is loaded - help would be greatly appreciated, thanks.

CodePudding user response:

For your kind information, Using late keyword means that the instant will be initialized when you use it for the first time. Like:

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

For more about sound null safety

More about lazy initialization

N.B: In your case, you can remove late, otherwise initialize it.

CodePudding user response:

instead of late Stream<QuerySnapshot> chatRoomsStream;

use Stream<QuerySnapshot>? chatRoomsStream;

and when you call the chatRoomStream call it as chatRoomStream! this is null safety know about null safety

  • Related