带有协程的 Firestore 快照?

Firestore Snapshot with Coroutines?

您好,我尝试制作 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 中的值时,它没有获取新数据... 任何人都知道为什么它没有修复

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

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 Class(主要片段)中:

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) }
}

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