I have been trying to get data from Firestore in a ListView.builder, which is inside a StreamBuilder<QuerySnapshot>. The itemCount for the ListView.builder is snapshot.data.docs.length.
I'm using plugin cloud_firestore: ^3.1.5.
Anytime i run the app, this is the error I get:
════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building StreamBuilder<QuerySnapshot<Object?>>(dirty, state: _StreamBuilderBaseState<QuerySnapshot<Object?>, AsyncSnapshot<QuerySnapshot<Object?>>>#3b903):
The getter 'docs' was called on null.
Receiver: null
Tried calling: docs
Here is the sample code:
Widget ChatMessageList() {
return StreamBuilder<QuerySnapshot>(
stream: chatMessageStream,
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
return snapshot != null
? ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return MessageTile(
chatTime: snapshot.data.docs[index].get("time"),
chatMessage: snapshot.data.docs[index].get('message'),
byMe: snapshot.data.docs[index].get('message') ==
widget.myName,
);
},
)
: Container();
},
);
}
So i decided to use another approach:
Widget ChatMessageList() {
return StreamBuilder(
stream: chatMessageStream as Stream,
builder: (context, snapshot) {
return snapshot?.data?.docs == true
? Container()
: ListView.builder(
itemCount: snapshot?.data?.docs?.length,
itemBuilder: (context, index) {
return MessageTile(
chatTime: snapshot?.data?.docs[index].get("time"),
chatMessage: snapshot?.data?.docs[index].get('message'),
byMe: snapshot?.data?.docs[index].get("sentBy") ==
widget.myName,
);
});
});
}
This new approach also returns this as error:
════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building:
The method '[]' was called on null.
Receiver: null
Tried calling: [](0)
Any help will be appreciated... Thanks in advance!
CodePudding user response:
Use as keyword for downcast as:
Widget ChatMessageList() {
return StreamBuilder<List<QuerySnapshot>>(
stream: chatMessageStream,
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot){
if (snapshot.data != null) {
final list = snapshot.data as List; // <-- Downcasting
return ListView.builder(
itemCount: list.length,
itemBuilder: (context, index)
{
return MessageTile(
chatTime: snapshot.data.docs[index].get("time"),
chatMessage: snapshot.data.docs[index].get('message'),
byMe: snapshot.data.docs[index].get('message') ==
widget.myName,
);
},
//
CodePudding user response:
Update the null check logic snapshot?.data?.docs in place of snapshot != null
Other code looks fine
Widget ChatMessageList() {
return StreamBuilder<QuerySnapshot>(
stream: chatMessageStream,
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
return snapshot?.data?.docs != null
? ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
return MessageTile(
chatTime: snapshot.data.docs[index].get("time"),
chatMessage: snapshot.data.docs[index].get('message'),
byMe: snapshot.data.docs[index].get('message') ==
widget.myName,
);
},
)
: Container();
},
);
}
