Firestore-Flutter:使用’whereIn’查询大于10个项目

huangapple go评论50阅读模式
英文:

Firestore-Flutter: Query with 'whereIn' Greater than 10 items

问题

我有一个接受 Firestore 'Query' 的函数,具体来说是 `Query<Map<String, dynamic>>`(不是 'QuerySnapshot')。我必须执行的查询之一包含一个可能超过10个的列表项。我知道 'whereIn' 函数不能接受超过10个项目,所以有没有办法遍历这些 'Queries' 并返回多个 `Query` 而不是 `QuerySnapshots`?当 'teamRecord.usersInTeam.length' 小于10时,一切都正常运行。

我尝试为 'Snapshots' 实现类似的解决方案 [这里][1],但我无法使其返回一个 `Query`。

以下是错误。我不确定如何使 'subList.forEach()' 返回一个 `Query`。
```dart
A value of type 'void' can't be returned from the method 'GetUsersInTeams' because it has a return type of 'Query<Map<String, dynamic>>'.

我还尝试了以下函数,它返回了前10条记录,但不再返回更多。

int _start = 0;
int _end = 10;

Query<Map<String, dynamic>> getUsersInTeams() {
    List<DocumentReference> usersInTeam = widget.teamRecord.usersInTeam.asList();
    print('usersInTeam ${usersInTeam.length}');
    if (_end >= usersInTeam.length) {
      _end = usersInTeam.length;
    }

    List<DocumentReference> nextUsersInTeam = usersInTeam.sublist(_start, _end);
    print('nextUsersInTeam ${nextUsersInTeam.length}');

    final results = FirebaseFirestore
        .instance
        .collection('activity_units')
        .orderBy('activity_value', descending: true)
        .where('challenge_reference', isEqualTo: widget.challenges.reference)
        .where('user_inchallenge', whereIn: nextUsersInTeam);

    // 更新下一个查询的起始和结束索引
    _start = _end;
    _end += 10;

    return results;
}

<details>
<summary>英文:</summary>

I have a function that takes in a Firestore &#39;Query&#39;, specifically `Query&lt;Map&lt;String, dynamic&gt;&gt;` (not a &#39;QuerySnapshot&#39;). One of the queries I have to do has an item that is a list that can be &gt;10. I know the &#39;whereIn&#39; function cannot accept more than 10 items, so is there a way to iterate through the `Queries` and return multiple `Query&#39;s` instead of `QuerySnapshots`? Everything works fine when &#39;teamRecord.usersInTeam.length&#39; is &lt; 10. 
FirebaseFirestore
          .instance
          .collection(&#39;activity_units&#39;)
          .orderBy(&#39;activity_value&#39;, descending: true)
          .where(&#39;challenge_reference&#39;, isEqualTo: widget.challenges.reference)
//the teamRecord.usersInTeam cannot be &gt; 10 and this where the error is thrown
          .where(&#39;user_inchallenge&#39;, whereIn: teamRecord.usersInTeam.asList());
I tried to implement a similar solution for `Snapshots` found [here][1], but I could not get it work to return a `Query`.

Query<Map<String, dynamic>> GetUsersInTeams() {
List<DocumentReference> usersInTeam = teamRecord.usersInTeam.asList();
List<List<DocumentReference>> subList = [];
for (var i = 0; i < usersInTeam.length; i += 10) {
subList.add(
usersInTeam.sublist(i, i + 10 > usersInTeam.length ? usersInTeam.length : i + 10)
);
}

final results =
      subList.forEach((element) {
       Query test = FirebaseFirestore
            .instance
            .collection(&#39;activity_units&#39;)
            .orderBy(&#39;activity_value&#39;, descending: true)
            .where(&#39;challenge_reference&#39;, isEqualTo: widget.challenges.reference)
            .where(&#39;user_inchallenge&#39;, whereIn: element);
      });
      return results;

}

The error here is below. I am not sure how to make `subList.forEach()` return a `Query`. 

A value of type 'void' can't be returned from the method 'GetUsersInTeams' because it has a return type of 'Query<Map<String, dynamic>>'.


I also tried the following function, and it returned the first 10 records, but not anymore.
int _start = 0;
int _end = 10;

Query&lt;Map&lt;String, dynamic&gt;&gt; getUsersInTeams() {
    List&lt;DocumentReference&gt; usersInTeam = widget.teamRecord.usersInTeam.asList();
    print(&#39;usersInTeam ${usersInTeam.length}&#39;);
    if (_end &gt;= usersInTeam.length) {
      _end = usersInTeam.length;
    }

    List&lt;DocumentReference&gt; nextUsersInTeam = usersInTeam.sublist(_start, _end);
    print(&#39;nextUsersInTeam ${nextUsersInTeam.length}&#39;);

    final results = FirebaseFirestore
        .instance
        .collection(&#39;activity_units&#39;)
        .orderBy(&#39;activity_value&#39;, descending: true)
        .where(&#39;challenge_reference&#39;, isEqualTo: widget.challenges.reference)
        .where(&#39;user_inchallenge&#39;, whereIn: nextUsersInTeam);

    // Update start and end indices for next query
    _start = _end;
    _end += 10;
 
    return results;
  }


  [1]: https://stackoverflow.com/a/68711077/16806413

</details>


# 答案1
**得分**: 1

最新的SDK实际上允许在一个IN子句中最多有30个项目(或者如果你也使用OR,那么跨所有析取操作)。但是从查看这里的代码(https://github.com/firebase/flutterfire/blob/81f1b80c445cfaab3e7752b8c58f35c92d234d8d/packages/cloud_firestore/cloud_firestore/lib/src/query.dart#L734)来看,Flutter SDK似乎还没有更新其检查。

我在FlutterFire仓库上提交了问题[#11085](https://github.com/firebase/flutterfire/issues/11085)来跟踪此问题。

<details>
<summary>英文:</summary>

The latest SDKs should actually allow up to 30 items in an IN clause (or across all disjunctions if you use OR too). But from looking at the code [here](https://github.com/firebase/flutterfire/blob/81f1b80c445cfaab3e7752b8c58f35c92d234d8d/packages/cloud_firestore/cloud_firestore/lib/src/query.dart#L734), it looks like the Flutter SDK might not have updated its check yet.

I filed issue [#11085](https://github.com/firebase/flutterfire/issues/11085) on the FlutterFire repo to track this.

</details>



huangapple
  • 本文由 发表于 2023年6月6日 05:02:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76409983.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定