Flutter Firebase Cloud Firestore get stream of list of documents by their ids

1,289

You can't directly listen to documents based on their ids, but you can add a field called docId (the value should be the id of the document) to each document then listen to collection with this where condition.

List listOfDocIds = []; // this is the list of your docIds
StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
  stream: FirebaseFirestore.instance
            .collection('users')
            .where('docId', whereIn: listOfDocIds),
  builder: (BuildContext context,
      AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
    if (snapshot.hasError) return Text('Something went wrong');
    if (snapshot.connectionState == ConnectionState.waiting)
      return CircularProgressIndicator();

    List<Map<String, dynamic>> data =
        snapshot.data.docs.map((e) => e.data()).toList();
    print(data);
    // you can build your widget here
    return ListView.builder(
      itemCount: data.length,
      itemBuilder: (context, i) {
        return ListTile(
          title: Text(data[i]['name']),
          // TODO: change 'name' to name of field in users document
        );
      },
    );
  },
),
Share:
1,289
viic
Author by

viic

Updated on January 01, 2023

Comments

  • viic
    viic over 1 year

    Hey guys I have two top level collections, a user and a tabs collection. Within each user document I have an array field of document ids with each element in the array representing a document in the tabs collection (sort of like a reference or a pointer to that document) and I would like to listen to real time changes in the users/document with the list of ID's and to listen for changes to the corresponding documents in the tabs collection.

    Below is my code so far and there are two issues with it. The stream isn’t working client side - I’m not receiving an updated snapshot when I update the document in cloud firestore. Also in order for me to get a list of tabIds I am currently making a query to cloud firestore which returns a stream however, the whereIn operator only accepts a list of objects so I’m not to sure how to handle that.

    data model screenshot

         Stream<List<Tab>> get tabs {
          var tabIds = _db.collection('users').doc(user.uid).snapshots().where((event) => event.get('tabs'));
          return _db
          .collection('tabs')
          .where(FieldPath.documentId, whereIn: tabIds)
          .snapshots()
          .map((list) =>
            list.docs.map((doc) => Tab.fromJson(doc.data())).toList());
         }
    
    • LeadDreamer
      LeadDreamer over 2 years
      There is a STRONG PREFERENCE for actual text, cut'n'pasted and formatted HERE - if only so other people (the entire point of stackEXCHANGE and stackOVERFLOW) can search for similar issues. At an absolute MINIMUM, the image should be posted HERE. EVen better, cut'n'paste the CODE you're having difficulty with.
    • viic
      viic over 2 years
      I did post an image but I'm not sure why its embedded in a link above the question. As far as code goes, that's the part I'm having difficulty with. I haven't been able to produce usable code for the question above. I'm new to firestore and firebase.
    • Jay
      Jay over 2 years
      We're not a code writing service so we need to see the code you've attempted, even if it doesn't work. Please take a moment and review How to create a Minimal, Complete, and Verifiable example. The question is also a bit unclear - do you want to listen for changes in the users/document with the list of ID's or do you want to use that list to listen for changes to the corresponding documents in the tabs collection?
    • viic
      viic over 2 years
      Honestly I’d like to do both.
    • Jay
      Jay over 2 years
      Please don't post code in comments; it's impossible to read. Update the question with your code and an explanation of what it does - or at least what you're attempting to do. Then we'll take a look!
    • viic
      viic over 2 years
      Hey jay let me know if that's better or you need a bit more information.
  • viic
    viic over 2 years
    thanks for the answer peter but the stream I am actually trying to get is a snapshot of the stream of documents belonging to that user and not a snapshot of the user collection. I have an array field that contains document ids for documents within another collection and what I am trying to do is to be able to listen to any changes that are made to those specific documents.
  • Peter Obiechina
    Peter Obiechina over 2 years
    To be sure I understand you correctly, you want to listen to documents whose id are in a a list?. I have updated my answer. It should listen to changes for all documents in listOfDocIds. Check it out.
  • viic
    viic over 2 years
    I tried doing something very similar to that with some valid hard coded document ids to test it out but my stream seems to be empty. is there a reason its like that. below is my code. It doesn't seem to want to enter my map functions
  • Peter Obiechina
    Peter Obiechina over 2 years
    I think whereIn: Ids should be whereIn: tabIds;
  • Peter Obiechina
    Peter Obiechina over 2 years
    Let me know if that works.
  • viic
    viic over 2 years
    Hey Peter could you take a look at the updated question.
  • ShadeToD
    ShadeToD over 2 years
    Note that whereIn has some limitation. "you're currently limited to a maximum of 10 different values in your queries."