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