如何在 firebase 数据库中使用 kotlin 协程
How to use kotlin coroutines in firebase database
我正在尝试使用 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.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)
}
}
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
}
这假设您从 CoroutineScope
.
对象调用 launch
第一个代码片段中 runBlocking{..}
的用法如下:runBlocking
函数 blocks 执行参数 lambda 代码(和 lambda代码将在内部暂停)。它的意义不大。
您可能希望使用 launch{..}
函数启动协程,并使用 withContext(Dispatchers.Main){..}
使块在 UI 线程中执行,例如显示获取的结果。您也可以在 activity class.
中实现 CoroutineScope
第一步 - 您需要将 Firebase API 调用转换为挂起函数。它可以用 suspendCoroutine{..}
函数来完成(在 kotlinx.coroutines 库中还有几个像 suspendCancellableCoroutine{..}
的函数。
有一个带有 Google Play Services 的集成库,为 Firebase
提供支持
https://github.com/Kotlin/kotlinx.coroutines/tree/master/integration/kotlinx-coroutines-play-services
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"
我正在尝试使用 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.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)
}
}
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
}
这假设您从 CoroutineScope
.
launch
第一个代码片段中 runBlocking{..}
的用法如下:runBlocking
函数 blocks 执行参数 lambda 代码(和 lambda代码将在内部暂停)。它的意义不大。
您可能希望使用 launch{..}
函数启动协程,并使用 withContext(Dispatchers.Main){..}
使块在 UI 线程中执行,例如显示获取的结果。您也可以在 activity class.
CoroutineScope
第一步 - 您需要将 Firebase API 调用转换为挂起函数。它可以用 suspendCoroutine{..}
函数来完成(在 kotlinx.coroutines 库中还有几个像 suspendCancellableCoroutine{..}
的函数。
有一个带有 Google Play Services 的集成库,为 Firebase
提供支持
https://github.com/Kotlin/kotlinx.coroutines/tree/master/integration/kotlinx-coroutines-play-services
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"