【问题标题】:Firestore Snapshot with Coroutines?使用协程的 Firestore 快照?
【发布时间】:2021-05-31 03:03:11
【问题描述】:

您好,我尝试制作 Coroutines Flow(使用 callbackFlow)并尝试将其转换为实时数据,但它似乎没有更新。

你可以在下面看到我的代码:

@ExperimentalCoroutinesApi
suspend fun checkInDanger(): Flow<NetworkStatus<List<UserFire>>> = callbackFlow {
    val check = fs.collection(UserFire.COLLECTION).whereEqualTo(UserFire.DANGER, true)
        .addSnapshotListener { value, e ->
            if (e != null) {
                trySend(NetworkStatus.Failed("Error occurred\n${e.code}"))
                return@addSnapshotListener
            }
            if (value == null || value.isEmpty) trySend(NetworkStatus.Empty)
            else {
                val users = value.map { it.toObject(UserFire::class.java) }
                trySend(NetworkStatus.Success(users))
            }
        }
    awaitClose {  }
}.flowOn(Dispatchers.IO)

在我的存储库中:

@ExperimentalCoroutinesApi
override suspend fun checkInDanger(): Flow<Status<List<User>>> = flow {
    when (val result = network.checkInDanger().first()) {
        is NetworkStatus.Success -> emit(Status.Success(result.data.map {
            MapVal.userFireToDom(it)
        }))
        is NetworkStatus.Empty -> emit(Status.Success(listOf<User>()))
        is NetworkStatus.Failed -> emit(Status.Error(null, result.error))
    }
}

在我的 ViewModel 中:

val checkInDanger = liveData(Dispatchers.IO) {
    try {
        useCase.checkInDanger().collectLatest {
            emit(it)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

但是当我更改 Firebase 中的值时,它并没有获取新数据... 任何人都知道为什么它没有修复

【问题讨论】:

    标签: android firebase google-cloud-firestore android-livedata


    【解决方案1】:

    我找到了方法,但它是使用回调,如果我们使用回调,即使没有实时数据,它也可以获取数据更新,但就我而言,我尝试再次将回调推送到实时数据, 所以代码会是这样的:

    fun checkInDanger(networkStatus: (NetworkStatus<List<UserFire>>) -> Unit) {
        fs.collection(UserFire.COLLECTION).whereEqualTo(UserFire.DANGER, true)
            .addSnapshotListener { value, e ->
                if (e != null) {
                    networkStatus(NetworkStatus.Failed("Error occurred\n${e.code}"))
                    return@addSnapshotListener
                }
                if (value == null || value.isEmpty) networkStatus(NetworkStatus.Empty)
                else {
                    val users = value.map { it.toObject(UserFire::class.java) }
                    networkStatus(NetworkStatus.Success(users))
                }
            }
    }
    

    在我的存储库中:

    override fun checkInDanger(callback: (Status<List<User>>) -> Unit) {
        network.checkInDanger { result ->
            when (result) {
                is NetworkStatus.Success -> callback(Status.Success(result.data.map {
                    MapVal.userFireToDom(it)
                }))
                is NetworkStatus.Empty -> callback(Status.Success(listOf<User>()))
                is NetworkStatus.Failed -> callback(Status.Error(null, result.error))
            }
        }
    }
    

    在我的 ViewModel 中:

    fun checkInDanger(callback: (Status<List<User>>) -> Unit) = useCase.checkInDanger { callback(it) }
    
    val setUsers = MutableLiveData<List<User>>().apply { this.value = listOf() }
    val users: LiveData<List<User>> = setUsers
    

    在我的 UI 类(主要片段)中:

    val inDangerCallback: (Status<List<User>>) -> Unit =  {
        if (relative != null) {
            when (it) {
                is Status.Success ->
                    viewModel.setUsers.value =
                        it.data?.filter { user -> user.username in relative!!.pure }
                else -> requireView().createSnackBar(it.error!!, 1000)
            }
        }
    }
    viewModel.checkInDanger(inDangerCallback)
    
    viewModel.users.observe(viewLifecycleOwner) { users ->
        println(users.size})
        users?.forEach { user -> println(user.username) }
    }
    

    并且代码可以完美运行并自动更新...

    【讨论】:

      猜你喜欢
      • 2021-11-24
      • 2019-07-23
      • 2021-06-17
      • 2019-08-22
      • 1970-01-01
      • 2020-12-16
      • 1970-01-01
      • 2021-09-27
      • 2018-12-27
      相关资源
      最近更新 更多