英文:
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 'Query', specifically `Query<Map<String, dynamic>>` (not a 'QuerySnapshot'). One of the queries I have to do has an item that is a list that can be >10. I know the 'whereIn' function cannot accept more than 10 items, so is there a way to iterate through the `Queries` and return multiple `Query's` instead of `QuerySnapshots`? Everything works fine when 'teamRecord.usersInTeam.length' is < 10.
FirebaseFirestore
.instance
.collection('activity_units')
.orderBy('activity_value', descending: true)
.where('challenge_reference', isEqualTo: widget.challenges.reference)
//the teamRecord.usersInTeam cannot be > 10 and this where the error is thrown
.where('user_inchallenge', 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('activity_units')
.orderBy('activity_value', descending: true)
.where('challenge_reference', isEqualTo: widget.challenges.reference)
.where('user_inchallenge', 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<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);
// 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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论