【问题标题】:How can I deal with the firestore whereIn limit of 10 when using a switch stream?使用切换流时如何处理限制为 10 的 Firestore?
【发布时间】:2020-09-05 16:15:02
【问题描述】:

我有以下 Stream 接收组的 Stream 并返回其成员的 Stream。我使用 switchmap 从组快照中获取成员。

但是我有以下问题。我使用带有whereIn 过滤器的where 查询。但问题是 whereIn 根据 firestore 文档只能接收包含 10 个或更少条目的列表

限制 请注意以下对 in 和 数组包含任何:

in 和 array-contains-any 最多支持 10 个比较值。

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

所以我在这个场景中处理这个问题时遇到了一些困难。

  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)),
    );
  }

因为我需要以组成员 ID 开头,所以我需要一个 switchMap。所以我不能简单地拆分组成员列表,然后对 10 个 id 的每个块进行单独查询。

那么我该如何处理呢?

【问题讨论】:

    标签: flutter dart google-cloud-firestore rxdart


    【解决方案1】:

    另一种可能的解决方案(使用 QuiverRxDart 包)

      Future<List<QueryDocumentSnapshot>> listItems(
          List<dynamic> itemIds) async {
        final chunks = partition(itemIds, 10);
        final querySnapshots = await Future.wait(chunks.map((chunk) {
          Query itemsQuery = FirebaseFirestore.instance
              .collection('collection')
              .where("id", whereIn: chunk);
          return itemsQuery.get();
        }).toList());
        return querySnapshots == null
            ? []
            : await Stream.fromIterable(querySnapshots)
                .flatMap((qs) => Stream.fromIterable(qs.docs))
                .toList();
      }
    

    这样看起来更通用(您甚至可以使用供应商函数排除查询)。

    【讨论】:

      【解决方案2】:

      我最终是这样做的

        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);
        }
      

      【讨论】:

      • chunkSizeCollection 是什么?
      • Firestore whereIn 有 10 个元素的限制。 chunkSizeCollection 只是将数组拆分为 10 个元素的块。
      • 迈克,我修改了这段代码,我得到了一个 throw 在 null 上调用了方法“add”。接收方:null 尝试调用:add(Instance of '_MapStream>')。 .add 需要等待......你没有得到那个吗?我遇到的问题是 await 需要一个使流短路的未来。想知道我是否遗漏了什么。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-08
      相关资源
      最近更新 更多