如何在Firebase数据库中使用Kotlin协程

问题描述:

我正在尝试使用Firestore和协程进入聊天室.

I'm trying to access chatting room Using firestore and coroutines.

    fun getOwner() {
        runBlocking {
            var de = async(Dispatchers.IO) {
                firestore.collection("Chat").document("cF7DrENgQ4noWjr3SxKX").get()
            }
            var result = de.await().result
        }

但是我得到这样的错误:

But i get error like this :

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时,我可以访问聊天室文档.

How can i get chat document? when i use origin api like below, I can access chat room document.

        firestore.collection("Chat").document(
            "cF7DrENgQ4noWjr3SxKX"
        ).get().addOnCompleteListener { task ->
            if (task.isSuccessful) {
                val chatDTO = task.result?.toObject(Appointment::class.java)
            }
        }

Task是等待的事情,但是您将其包装在async的另一层中.删除async:

Task is the thing one awaits on, but you wrapped it in another layer of async. Remove the async:

fun getOwner() {
    runBlocking {
        var de =  firestore.collection("Chat").document("cF7DrENgQ4noWjr3SxKX").get()
        var result = de.await().result
    }
}

但是,通过使用runBlocking(),您已经陷入僵局,并编写了阻塞代码,这些代码只是正式使用异步API效果不佳.

However, by using runBlocking() you have shot yourself in the foot and wrote blocking code that just formally uses an async API to no good effect.

要真正从中受益,您必须拥有

To truly benefit from it, you must have a

suspend fun getOwner() = firestore
     .collection("Chat")
     .document("cF7DrENgQ4noWjr3SxKX")
     .get()
     .await()
     .result

launch协程在您从其调用的位置:

and launch a coroutine at the place you call it from:

launch {
    val owner = getOwner()
    // update the GUI
}

这假设您正在从CoroutineScope的对象中调用launch.

This assumes you're calling launch from an object that is a CoroutineScope.