FireStore 不返回所有结果
Posted
技术标签:
【中文标题】FireStore 不返回所有结果【英文标题】:FireStore not return all results 【发布时间】:2021-06-21 23:11:48 【问题描述】:我想从 firestore 获取数据,假设我在一个集合中有 10 个文档。之后我必须在每个文档中获取数据,所以我将数据保存在 ArrayList 中。但是 FireBase 永远不会返回集合中的所有文档。有时它只返回包含 10 个文档的集合中的 5 ,6 个文档。
我的 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”)。 请告诉我有什么解决办法。提前致谢。
【问题讨论】:
【参考方案1】:您遇到的问题是您希望查询按如下顺序运行:
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
或addOnCompleteListener
来处理这些失败的任务。
更正确和正确的方法是使用Tasks.whenAll
,它的使用方式与使用Promise.all
查看javascript 答案的方式类似。我自己还是 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
这将允许您将以下内容与其他 Task
和 Tasks
方法一起使用。
getDocumentByQueryAList(idQueryList)
.addOnSuccessListener /* ... */
.addOnFailureListener /* ... */
【讨论】:
@HoanCong 如果这解决了你的问题,别忘了mark it as the accepted answer。【参考方案2】:使用 RxJava 像这样使用 smth:
override fun getAllDocs(): Single<List<MyClass>>
return Single.create emitter ->
db.collection("myCollection").get()
.addOnSuccessListener documents ->
val list = mutableListOf<MyClass>()
documents.forEach document ->
list.add(mapDocumentToMyClass(document))
emitter.onSuccess(list)
.addOnFailureListener exception ->
emitter.onError(exception)
private fun mapDocumentToMyClass(documentSnapshot: QueryDocumentSnapshot) =
MyClass(
documentSnapshot.get(ID).toString(),
documentSnapshot.get(SMTH).toString(),
// some extra fields
null
)
或者像这样使用协程:
override suspend fun getAllDocs(): List<MyClass>
return try
val snapshot =
db.collection("myCollection")
.get()
.await()
snapshot.map
mapDocumentToMyClass(it)
catch (e: Exception)
throw e
此功能可帮助您从一个文档中获取所有数据
【讨论】:
以上是关于FireStore 不返回所有结果的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Firestore 有时不返回任何内容,没有错误,啥也没有?
如何从 firestore 两个集合中获取数据并将所有数据合并在一起