skip to Main Content

I have collection for Users and groups, I want to display list of last update groups. But, the user uid must be stay in member field(array) of group Collection.

So, I use StreamBuilder and get snapshot like this,

FirebaseFirestore.instance
                .collection("groups")
                .orderBy('LastUpdate', descending: true)
                .where(
                  "members",
                  isEqualTo: FirebaseAuth.instance.currentUser!.uid,
                )
                .snapshots()

group collection {

  • LastUpdate filed type is timestamp,
  • members filed type is array
    }

There is a screenshot of firebase database group collection,

enter image description here

This is fullcode, When it run, it shows a error

StreamBuilder(
        stream: FirebaseFirestore.instance
            .collection("groups")
            .orderBy('LastUpdate', descending: true)
            .where(
              "members",
              isEqualTo: FirebaseAuth.instance.currentUser!.uid,
            )
            .snapshots(),
        builder: (context, AsyncSnapshot snapshot) {
          if (snapshot.hasError) {
            return Text(
              '${snapshot.error}',
              style: const TextStyle(color: Colors.white),
            );
          }
          if (snapshot.hasData) {
            return Padding(
              padding: const EdgeInsets.only(top: 5),
              child: ListView.builder(
                itemCount: 2, // <---- want to set length of groups - user have
                itemBuilder: (context, index) {
                  return Text(
                    snapshot.data['groupName'],
                    style: const TextStyle(fontSize: 40, color: Colors.white),
                  );
                },
              ),
            );
          } else {
            return const Center(
              child: CircularProgressIndicator(color: Colors.white),
            );
          }
        });

Error says –

════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building:
Class '_JsonQuerySnapshot' has no instance method '[]'.
Receiver: Instance of '_JsonQuerySnapshot'
Tried calling: []("groupName")

Main problem is that. and other thing is want to set count of groups user have. I set above code itemCount: 2,.

Please help to complete my code.

2

Answers


  1. By calling data on stream result you access to the QuerySnapshot inside that so you need to call .docs to access the document inside that and after that run ListView on those docs, so instead of use snapshot.data use snapshot.data.docs:

     ListView.builder(
        itemCount: snapshot.data.docs.length,
        itemBuilder: (context, index) {
          var data = snapshot.data.docs[index].data();
          return Text(
            data['groupName'],
            style: const TextStyle(fontSize: 40, color: Colors.white),
          );
        },
      ),
    

    also replace isEqualTo with arrayContains:

    FirebaseFirestore.instance
            .collection("groups")
            .orderBy('LastUpdate', descending: true)
            .where( "members", arrayContains: FirebaseAuth.instance.currentUser!.uid, )
            .snapshots(),
    
    Login or Signup to reply.
  2. .snapshot() return a Stream of an instance of QuerySnapshot as you can do when you use .get() you can access the result (the list of docs) by the .docs property.

    Said that your code can be changed like the following:

    StreamBuilder(
          stream: FirebaseFirestore.instance
              .collection("groups")
              .orderBy('LastUpdate', descending: true)
              .where(
            "members",
            isEqualTo: FirebaseAuth.instance.currentUser!.uid,
          )
              .snapshots(),
          builder: (context, AsyncSnapshot snapshot) {
            if (snapshot.hasError) {
              return Text(
                '${snapshot.error}',
                style: const TextStyle(color: Colors.white),
              );
            }
            if (snapshot.hasData) {
              final docs = snapshot.data.docs;
              return Padding(
                padding: const EdgeInsets.only(top: 5),
                child: ListView.builder(
                  itemCount: docs.length,
                  itemBuilder: (context, index) {
                    return Text(
                      docs[index].data['groupName'],
                      style: const TextStyle(fontSize: 40, color: Colors.white),
                    );
                  },
                ),
              );
            } else {
              return const Center(
                child: CircularProgressIndicator(color: Colors.white),
              );
            }
          });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search