android - FireStore 不返回所有结果
问题描述
我想从 firestore 获取数据,假设我在一个集合中有 10 个文档。之后我必须在每个文档中获取数据,所以我将数据保存在 ArrayList 中。但是 FireBase 永远不会返回集合中的所有文档。有时它只返回 5 ,6 个文档,集合中有 10 个文档。
我的 fireBaseUtil :
fun getDocumentByQueryAList( idQuery: List<String>, callBack: (ArrayList<DocumentSnapshot>) -> Unit) {
val listDocumentSnapshot = ArrayList<DocumentSnapshot>()
collRef = fireStore.collection("myCollection")
val size = idQuery.size
for (i in 0 until size) {
val query = collRef.whereEqualTo("fieldQuery", idQuery[i])
query.get().addOnSuccessListener { documents ->
for (document in documents) {
listDocumentSnapshot.add(document)
if (i == size - 1) {
callBack.invoke(listDocumentSnapshot)
}
}
}
}
}
我在 size = 10 时注销,但 i = 8 它调用了 invoke....
用户存储库:
FireBaseUtil.getDocumentByQueryAList{
// myList.addAll(listGettedByCallback)
}
->> 当我想在我的列表中有数据时,我调用 FireBaseUtil.getDocumentByQueryAList。我知道firebase异步返回值,但我不知道如何获取我的所有文档然后receiver.invoke(“callbackValue”)。请告诉我有什么解决办法。预先感谢。
解决方案
您遇到的问题是您希望查询按如下顺序运行:
get idQuery[0], then add to list, then
get idQuery[1], then add to list, then
get idQuery[2], then add to list, then
...
get idQuery[8], then add to list, then
get idQuery[9], then add to list, then
invoke callback
但实际上,以下所有事情都是并行发生的。
get idQuery[0] (add to list when finished)
get idQuery[1] (add to list when finished)
get idQuery[2] (add to list when finished)
...
get idQuery[8] (add to list when finished)
get idQuery[9] (add to list and invoke callback when finished)
如果在get idQuery[9]
其他一些之前完成,您将在列表完全填满之前调用您的回调。
解决此问题的一种原始方法是计算完成的 get 查询的数量,当所有查询都完成时,然后调用回调。
fun getDocumentByQueryAList( idQuery: List<String>, callBack: (ArrayList<DocumentSnapshot>) -> Unit) {
val listDocumentSnapshot = ArrayList<DocumentSnapshot>()
collRef = fireStore.collection("myCollection")
val size = idQuery.size
val finishedCount = 0
for (i in 0 until size) {
val query = collRef.whereEqualTo("fieldQuery", idQuery[i])
query.get().addOnSuccessListener { documents ->
for (document in documents) {
listDocumentSnapshot.add(document)
}
if (++finishedCount == size) { // ++finishedCount will add 1 to finishedCount, and return the new value
// all tasks done
callBack.invoke(listDocumentSnapshot)
}
}
}
}
但是,如果任何查询失败,这将遇到永远不会调用回调的问题。您可以使用addOnFailureListener
oraddOnCompleteListener
来处理这些失败的任务。
做你所期望的更正确和正确的方法是使用Tasks.whenAll
,它的使用方式与你看到 JavaScript 答案的方式相似Promise.all
。我自己还是 Kotlin 语法的新手,所以预计下面的代码块可能会引发错误。
fun getDocumentByQueryAList( idQueryList: List<String>, callBack: (ArrayList<DocumentSnapshot>) -> Unit) {
val listDocumentSnapshot = ArrayList<DocumentSnapshot>()
collRef = fireStore.collection("myCollection")
val getTasks = new ArrayList<Task<Void>>();
for (idQuery in idQueryList) {
val query = collRef.whereEqualTo("fieldQuery", idQuery)
getTasks.add(
query.get()
.onSuccessTask { documents ->
// if query succeeds, add matching documents to list
for (document in documents) {
listDocumentSnapshot.add(document)
}
}
)
}
Tasks.whenAll(getTasks)
.addOnSuccessListener { results ->
callback.invoke(listDocumentSnapshot)
}
.addOnFailureListener { errors ->
// one or more get queries failed
// do something
}
}
除了使用回调之外,您还可以返回一个 Task ,最后一位是:
return Tasks.whenAll(getTasks)
.onSuccessTask { results ->
return listDocumentSnapshot
}
getDocumentByQueryAList(idQueryList)
.addOnSuccessListener { /* ... */ }
.addOnFailureListener { /* ... */ }
推荐阅读
- python - 在数组 Python 上拆分 valeus
- javascript - 从查询转换为数字失败。Node.js Express 猫鼬
- amazon-web-services - 创建 AWS Elasticsearch 域时出错 - 错误设置策略
- http - 在使用 https 的站点上从 http 输出视频图像
- ios - 无法在 macOS (x86_64) 上为 iPhone (arm64) 交叉编译静态 C 库
- java - Spring boot 执行没有错误,但是服务器上没有创建表
- vb.net - 后期绑定:期待错误但没有得到它
- javascript - TypeError:预期现有数据是数字,接收到的字符串
- python - 如何一次在 Django 模型中保存多个对象
- python - 如何检查字符后是否有整数?