You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用StateFlow从Firestore实时更新订单列表遇类型不匹配错误

解决Firestore实时更新订单列表的类型不匹配问题

问题原因

你遇到的类型不匹配错误,本质是把Flow<List<OrderModel>>直接传给了需要List<OrderModel>的State.success()方法。snapshotFlow()返回的是持续发射Firestore快照数据的流,而非单次的列表数据,不能直接作为Success状态的参数。

修复方案

1. 修正RepositoryImp中的getAllOrders方法

需要收集snapshotFlow的实时数据流,每次收到新的订单列表时发射State.success状态:

class RepositoryImp : Repository {
    private fun Query.snapshotFlow(): Flow<QuerySnapshot> = callbackFlow {
        val listener = addSnapshotListener { value, error ->
            if (error != null) {
                trySendError(error) // 将错误传递到外层Flow
                close()
                return@addSnapshotListener
            }
            value?.let { trySend(it) }
        }
        awaitClose { listener.remove() }
    }

    override fun getAllOrders() = flow<State<List<OrderModel>>> {
        emit(State.loading())
        // 实时收集Firestore的快照数据流
        ORDER_COLLECTION_REF.snapshotFlow()
            .mapNotNull { it.toObjects(OrderModel::class.java) }
            .collect { orderList ->
                // 每次收到新列表,发射Success状态
                emit(State.success(orderList))
            }
    }.catch {
        emit(State.failed(it.message ?: "未知错误"))
    }.flowOn(Dispatchers.IO)
}

2. 保留ViewModel中的加载逻辑

你的loadOrders方法无需修改,它会自动收集getAllOrders()返回的状态流,实时更新适配器数据:

private suspend fun loadOrders() {
    viewModel.getAllOrders().collect { state ->
        when (state) {
            is State.Loading -> showToast("Loading")
            is State.Success -> adapter.submitList(state.data)
            is State.Failed -> showToast("Failed! ${state.message}")
        }
    }
}

关键说明

  • 修正后的getAllOrders()会先发射Loading状态,然后持续监听Firestore的订单集合变化,每次有数据更新就发射包含最新列表的Success状态。
  • 新增的trySendError(error)会将Firestore的监听错误传递到外层的catch块,确保错误能被捕获并发射Failed状态。

内容的提问来源于stack exchange,提问作者soufiane morsel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 05:50:26