[英]firestore, coroutine and flow
firebase 方法自动在工作线程上工作。 但是我已经使用协程和回调流来同步实现 firebase 监听器代码或从监听器获取返回。 下面是我解释的代码
协程等待与 firebase 一枪
override suspend fun checkNickName(nickName: String): Results<Int> {
lateinit var result : Results<Int>
fireStore.collection("database")
.document("user")
.get()
.addOnCompleteListener { document ->
if (document.isSuccessful) {
val list = document.result.data?.get("nickNameList") as List<String>
if (list.contains(nickName))
result = Results.Exist(1)
else
result = Results.No(0)
//document.getResult().get("nickNameList")
}
else {
}
}.await()
return result
}
带有 firebase 监听器的回调流
override fun getOwnUser(): Flow<UserEntity> = callbackFlow{
val document = fireStore.collection("database/user/userList/")
.document("test!!!!!")
val subscription = document.addSnapshotListener { snapshot,_ ->
if (snapshot!!.exists()) {
val ownUser = snapshot.toObject<UserEntity>()
if (ownUser != null) {
trySend(ownUser)
}
}
}
awaitClose { subscription.remove() }
}
所以我真的很想知道这些方式是好是坏的做法及其原因
不要将addOnCompleteListener
与协程await()
结合使用。 不能保证在await()
之前或之后调用侦听器,因此在整个挂起 function 返回之前,侦听器中的代码可能不会被调用。 此外,首先使用协程的主要原因之一是避免使用回调。 所以你的第一个 function 应该如下所示:
override suspend fun checkNickName(nickName: String): Results<Int> {
try {
val userList = fireStore.collection("database")
.document("user")
.get()
.await()
.get("nickNameList") as List<String>
return if (userList.contains(nickName)) Results.Exist(1) else Results.No(0)
} catch (e: Exception) {
// return a failure result here
}
}
您对callbackFlow
的使用看起来不错,除了您应该向要返回的流添加一个buffer()
调用,以便您可以指定如何处理背压。 但是,您可能希望改为处理该下游。
override fun getOwnUser(): Flow<UserEntity> = callbackFlow {
//...
}.buffer(/* Customize backpressure behavior here */)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.