flutterdartgoogle-cloud-firestorerxdart

How can I deal with the firestore whereIn limit of 10 when using a switch stream?


I have the following Stream that takes in a Stream of a group and returns a Stream of it's members. I use a switchmap to get the members from the group snapshot.

But I have the following problem. I use a where query with a whereIn filter. But the problem is that the whereIn can only take in a list that have 10 entries or less according to the firestore documentation

Limitations Note the following limitations for in and array-contains-any:

in and array-contains-any support up to 10 comparison values.

https://firebase.google.com/docs/firestore/query-data/queries#limitations

So I am having some difficulties with dealing with that in this senario.

  Stream<List<UserModel>> groupMembersStream(Stream<GroupModel> groupStream) {
    return groupStream.switchMap(
      (value) => _fireStore
          .collection(APIRoutes.users)
          .where(FieldPath.documentId, whereIn: value.members.keys.toList(growable: false))
          .snapshots()
          .map((snapshot) =>
              snapshot.documents.map((document) => UserModel.fromFirestore(document)).toList(growable: false)),
    );
  }

Because I need the group member id's to start with so I need a switchMap. So I cannot just simply split up the group members list and then do a seperate query for each chunk of 10 id's.

So how do I deal with this?


Solution

  • I ended up doing it like this

      Stream<List<UserModel>> groupMembersStream(Stream<GroupModel> groupStream) {
        return groupStream.switchMap(
          (value) => _chunckSizeGroupMembersStream(value),
        );
      }
    
      Stream<List<UserModel>> _chunckSizeGroupMembersStream(GroupModel group) {
        final List<List<String>> memberChunks = chunkSizeCollection(group.members.keys.toList(growable: false), 10);
        List<Stream<List<UserModel>>> streams = List<Stream<List<UserModel>>>();
        memberChunks.forEach((chunck) => streams.add(_fireStore
            .collection(APIRoutes.userCollection)
            .where(FieldPath.documentId, whereIn: chunck)
            .snapshots()
            .map((snapshot) =>
                snapshot.documents.map((document) => UserModel.fromFirestore(document)).toList(growable: false))));
        return ZipStream(streams, (value) => value.last);
      }