skip to Main Content

In my database, I have a "Czat" collection and a "Wiadomosci" subcollecion. The Czat collection has documents that store users messages in ‘Wiadomosci’ and fields: idSender, idReceiver. I would like to retrieve all the Chat collection and all subcollections ‘Wiadomosci’ that has the idSender specified. To do this, I created a stream that retrieves the data of documents with specific idSender from Czat. Then it tries to get the id of the previously mentioned documents and in the next stream enter them in the doc(). This will allow me to retrieve data from the subcollection Wiadomosci. Unfortunately, a problem arises. The forEach loop does not execute. How can I fix this?

    return Scaffold(
      body: StreamBuilder(
        stream: FirebaseFirestore.instance
            .collection('Chat')
            .where('idSender', isEqualTo: 'O3EweI2Y3pjSHyUm0HPb')
            .snapshots(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {

            snapshot.data?.docs.forEach(
              (element) {
                Builder(
                  builder: (context) {
                    
                    Stream<List<Message>> readMessage() =>
                        FirebaseFirestore.instance
                            .collection('Chat')
                            .doc(element.id)
                            .collection('Wiadomosci')
                            .snapshots()
                            .map((snapshots) => snapshots.docs
                                .map((doc) => Message.fromJson(doc.data()))
                                .toList());

                    return StreamBuilder(
                      stream: readMessage(),
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          final message = snapshot.data!;
                          return ListView(
                            children: message.map(buildTest).toList(),
                          );
                        } else {
                          return const Center(
                            child: CircularProgressIndicator(),
                          );
                        }
                      },
                    );
                  },
                );
              },
            );

            return Text('');
          } else {
            return const Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      ),
    );

enter image description here

2

Answers


  1. This is what you return return Text(”);
    To check if i am right, change to any other String

    if has data, you could return ListView and in this listview, child could be another future, for every child in list

    Login or Signup to reply.
  2. try the following ;

    return Scaffold(
      body: StreamBuilder(
        stream: FirebaseFirestore.instance
            .collection('Chat')
            .where('idSender', isEqualTo: 'O3EweI2Y3pjSHyUm0HPb')
            .snapshots(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return ListView.builder(
              itemCount: snapshot.data?.docs.length,
              itemBuilder: (context, index) {
                final element = snapshot.data?.docs[index];
                return Builder(
                  builder: (context) {
                    Stream<List<Message>> readMessage() =>
                        FirebaseFirestore.instance
                            .collection('Chat')
                            .doc(element.id)
                            .collection('Wiadomosci')
                            .snapshots()
                            .map((snapshots) => snapshots.docs
                                .map((doc) => Message.fromJson(doc.data()))
                                .toList());
    
                    return StreamBuilder(
                      stream: readMessage(),
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          final message = snapshot.data!;
                          return ListView(
                            shrinkWrap: true,
                            physics: NeverScrollableScrollPhysics(),
                            children: message.map(buildTest).toList(),
                          );
                        } else {
                          return const Center(
                            child: CircularProgressIndicator(),
                          );
                        }
                      },
                    );
                  },
                );
              },
            );
          } else {
            return const Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      ),
    );
    

    here i used ListView.builder instead of forEach because here we are already useing the Builder widget as a child of the StreamBuilder widget.and for that using ListView.builder ensures that the builder widget is used as a child of the StreamBuilder widget that makes the code inside it to execute properly.

    please let me know any?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search