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

Shu*_*You 2 kotlin firebase google-cloud-firestore kotlin-coroutines

我正在尝试使用Firestore和协程访问聊天室。

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

但是我得到这样的错误:

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)
Run Code Online (Sandbox Code Playgroud)

我如何获得聊天文档?当我使用如下所示的Origin API时,我可以访问聊天室文档。

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

Nur*_*lov 7

 val db = FirebaseFirestore.getInstance()
override suspend fun saveBinToDB(bin: Bin): Result<Unit> {
    lateinit var result:Result<Unit>
    db.collection("bins")
        .add(bin)
        .addOnSuccessListener { documentReference ->
            Log.d(TAG, "DocumentSnapshot written with ID: ${documentReference.id}")
            result = Result.Success(Unit)
        }
        .addOnFailureListener { e ->
            Log.w(TAG, "Error adding document", e)
            result = Result.Error(Exception())
        }
        .await()
    return result
}

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.3.7"
Run Code Online (Sandbox Code Playgroud)


Mar*_*nik 6

Task是人们等待的东西,但是您将其包裹在的另一层中async。删除async

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

但是,通过使用该工具,runBlocking()您已经不知所措,并编写了阻塞代码,这些代码仅正式使用异步API并没有取得很好的效果。

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

suspend fun getOwner() = firestore
     .collection("Chat")
     .document("cF7DrENgQ4noWjr3SxKX")
     .get()
     .await()
     .result
Run Code Online (Sandbox Code Playgroud)

launch在你叫它的地方还有一个协程:

launch {
    val owner = getOwner()
    // update the GUI
}
Run Code Online (Sandbox Code Playgroud)

假设您launch要从的对象进行调用CoroutineScope

  • 您需要在 [org.jetbrains.kotlinx:kotlinx-coroutines-play-services](https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-play) 中定义的`Task.await()` -服务)。 (5认同)