我正在用kotlin制作一个android应用程序,但是我目前面临一个奇怪的问题。问题所在的函数是这样:
private fun getName(uids:List<String>):List<String> {
val nameList = mutableListOf<String>()
for (uid in uids) {
Firebase.firestore.collection("users").whereEqualTo("id", uid).get().addOnSuccessListener { documents ->
val name = documents.documents[0]["name"] as String
println("The name is $name")
nameList.add(name)
println("The namelist is $nameList")
}
println("The data above is $nameList")
}
println("The datahere is $nameList")
return nameList.toList()
}
这里我有一些用户ID,基于这些ID,我正在从Firebase Cloud Firestore数据库中获取名称,数据已成功获取,并且当我第一次在获取中打印namelist
时块,正在添加元素。但是,当在获取块外部打印nameList
时,我发现该元素未添加。我已附上图片。
您可以看到正在添加元素。但是之后,该元素消失了,列表变为空。
我真的很困惑为什么发生这种情况。
答案 0 :(得分:2)
原因是您希望异步作业充当同步作业。众所周知,从firestore
检索数据是一个异步过程(请注意addOnSuccessListener
)。因此,当函数返回nameList
(以及最后一个println
)时,该函数为空,因为尚未检索到firestore
的任何结果!
由于DocumentReference.get()
返回一个Task
对象,因此可以等待它。因此,您的功能可能是这样的:
@WorkerThread
private fun getName(uids: List<String>) {
val nameList = mutableListOf<String>()
for (uid in uids) {
val task = Firebase.firestore.collection("users").whereEqualTo("id", uid).get()
val documentSnapshot = Tasks.await(task)
val name = documentSnapshot.documents[0]["name"] as String
nameList.add(name)
}
nameList.toList()
}
请注意,在这种情况下,您应该在辅助线程(而非主线程)中调用此函数。