Home > Software design >  How to get data from Firestore into ListView.builder in flutter?
How to get data from Firestore into ListView.builder in flutter?

Time:01-08

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();
  },
);
  }
  •  Tags:  
  • Related