[英]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.