我正在尝试使用Firestore和协程进入聊天室。
fun getOwner() {
runBlocking {
var de = async(Dispatchers.IO) {
firestore.collection("Chat").document("cF7DrENgQ4noWjr3SxKX").get()
}
var result = de.await().result
}
但是我得到这样的错误:
E/AndroidRuntime: FATAL EXCEPTION: Timer-0
Process: com.example.map_fetchuser_trest, PID: 19329
java.lang.IllegalStateException: Task is not yet complete
at com.google.android.gms.common.internal.Preconditions.checkState(Unknown Source:29)
at com.google.android.gms.tasks.zzu.zzb(Unknown Source:121)
at com.google.android.gms.tasks.zzu.getResult(Unknown Source:12)
at com.example.map_fetchuser_trest.model.Repository$getOwner$1.invokeSuspend(Repository.kt:53)
如何获取聊天文档?当我使用如下所示的Origin API时,我可以访问聊天室文档。
firestore.collection("Chat").document(
"cF7DrENgQ4noWjr3SxKX"
).get().addOnCompleteListener { task ->
if (task.isSuccessful) {
val chatDTO = task.result?.toObject(Appointment::class.java)
}
}
答案 0 :(得分:4)
Task
是等待中的东西,但是您将其包装在async
的另一层中。删除async
:
fun getOwner() {
runBlocking {
var de = firestore.collection("Chat").document("cF7DrENgQ4noWjr3SxKX").get()
var result = de.await().result
}
}
但是,通过使用runBlocking()
,您已经陷入僵局,并编写了阻塞代码,这些代码只是正式使用异步API效果不佳。
要真正从中受益,您必须拥有
suspend fun getOwner() = firestore
.collection("Chat")
.document("cF7DrENgQ4noWjr3SxKX")
.get()
.await()
.result
和launch
在您来自以下位置的协程:
launch {
val owner = getOwner()
// update the GUI
}
这假设您正在从launch
的对象中调用CoroutineScope
。
答案 1 :(得分:1)
第一个代码段中runBlocking{..}
的用法如下:runBlocking
函数 blocks 执行参数lambda代码(lambda代码将在其中暂停) 。它的意义不大。
您可能想改为使用launch{..}
函数启动协程,并使用withContext(Dispatchers.Main){..}
在UI线程中执行该块,例如以显示提取的结果。您也可以在活动类中实现CoroutineScope
。
第一步-您需要将Firebase API调用转换为挂起函数。可以使用suspendCoroutine{..}
函数来完成(kotlinx.coroutines库中还有suspendCancellableCoroutine{..}
之类的其他几个函数。
有一个Google Play服务集成库,可为Firebase提供支持
https://github.com/Kotlin/kotlinx.coroutines/tree/master/integration/kotlinx-coroutines-play-services
答案 2 :(得分:0)
wq