flutterfirebasegoogle-cloud-firestore

Access Firestore subcollection in Flutter


I have a Flutter chat application.

The structure of FireStore is: chats (collection) > roomId (random generated id, which is a document) > users (collection) > email (email of the user, which is a document) > messages (collection) > messageId (random generated id, which is a document) > the actual chat.

When I use the following code it works. This gives all the messages in a room by a particular user.

FirebaseFirestore.instance
        .collection('chats')
        .doc(roomId)
        .collection('users')
        .doc(user)
        .collection('messages')
        .orderBy('timestamp', descending: true)
        .snapshots(),

However, I need to get a list of all the users in a room. This is the code that I tried and is not getting any result, empty list.

QuerySnapshot<Map<String, dynamic>> userCollection = await FirebaseFirestore.instance
          .collection('chats')
          .doc(roomId)
          .collection('users')
          .get();

Here is the rule that is set on the store.

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

I need to get the list of all the users in the room. Any help is appreciated.

Updated code that worked I updated the code that I used to send message to FireStore.

await FirebaseFirestore.instance.collection('chats').doc(widget.roomId).set({
      'createdAt': FieldValue.serverTimestamp(),
    }, SetOptions(merge: true));

    await FirebaseFirestore.instance
        .collection('chats')
        .doc(widget.rooomId)
        .collection('users')
        .doc(widget.user)
        .set({
      'joinedAt': FieldValue.serverTimestamp(),
    }, SetOptions(merge: true));

    await FirebaseFirestore.instance
        .collection('chats')
        .doc(widget.roomId)
        .collection('users')
        .doc(widget.user)
        .collection('messages')
        .add({
      'senderId': widget.user,
      'text': _messageController.text,
      'timestamp': FieldValue.serverTimestamp(),
      'isAdmin': widget.isAdmin
    });

Solution

  • If you're getting an empty result, the operation is allowed by your security rules - so those aren't the cause of the empty list.

    More likely, you don't actually have any documents in the /chats/$roomId/user collection. Keep in mind:

    If this is indeed the cause of your problem, the normal way out is to create a document for each user. It doesn't have to have much (or even any) fields, but the document needs to exist. Alternatively/additionally, you can use a document group query on the lower-level collections, to see if you can reconstitute the users from that.

    For more on this, also see: