Search code examples
flutterdartgoogle-cloud-firestore

Firestore: fetch a list of documents in sequence of requesting parameter list ordering


Problem: The order of post items I receive from firestore is not same as the order of post items that I am passing to firestore to fetch.

This is simplified data structure for users and posts looks something like this.

/root
    /users (collection)
        /user_id_a (document with fields)
            - user_id_a
            - user_name_aa
            - bookmark_list
        /user_id_b (document with fields)
            - user_id_b
            - user_name_aa
            - bookmark_list

    /posts (collection)
        /post_id_c (document with fields)
            - post_id_c
            - post_title
            - posted_by
            - created_at
        /post_id_d (document with fields)
            - post_id_d
            - post_title
            - posted_by
            - created_at

What I am trying to achieve is to add bookmark feature with this data structure. I am now able to collect post_ids that a user wants to save as bookmark at bookmark_list field in user document. when user wants to see the list of bookmark on a screen, this code below is called. (language Dart is used)

await _firebaseFirestore
        .collection(_pathPosts)
        .where(FieldPath.documentId, whereIn: userProfileModel.bookmarkList)
        .withConverter(
      fromFirestore: PartiesPostModel.fromFirestore,
      toFirestore: (PartiesPostModel value, _) => value.toJson(),
    )
        .get()
        .then(
          (QuerySnapshot<PartiesPostModel> querySnapshot) {
        logger.i("bookmark list successfully fetched");
        List<PartiesPostModel> l = [];
        for (var docSnapshot in querySnapshot.docs) {
          l.add(docSnapshot.data());
        }
        return l;
      },
      onError: (e) {
        logger.e("Error completing: $e");
        return List.empty();
      }

since I am passing list of post_ids in userProfileModel.bookmarkList and post_ids were generated as random combination of alphabets by firestore when being collected, when fetch was done, their sequence are ordered by firestore's default way using documentId regardless of the sequence of post_ids in userProfileModel.bookmarkList that I am passing with. Is there any way I could fetch those posts documents in order of how bookmark items are in order in userProfileModel.bookmarkList rather than how firestore order by documentId? I will also appreciate if you suggest any other suggestions to make it work.
Thank you in advance.


Solution

  • The where conditions of a query control which documents are returned, but not in what order they are returned.

    The only way to control the order in which Firestore returns documents is with an orderBy statement. If you can't express your requirement in an orderBy (which seems to be the case), you will need to reorder the results in your application code. Since querySnapshot.docs contains all documents and their data, that should be pretty simple - and (more importantly) take almost no time.