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

Android(Kotlin+Jetpack Compose)从Firebase Firestore取数得空列表

解决Firestore获取数据返回空列表的问题

问题场景

使用Android(Kotlin+Jetpack Compose)从Firebase Firestore获取数据时,始终得到长度为0的列表,但数据库中实际存在数据。以下是问题代码的错误排查及修正方案:

原代码核心问题

  1. Repository层逻辑错误

    • 调用document("")指定了空文档ID,实际需要获取整个Products集合的数据,而非单个空文档
    • 混用Firestore回调API与协程suspend函数,导致协程无法正确返回数据,ViewModel拿不到有效结果
    • 返回类型Any过于宽泛,不符合业务逻辑
  2. ViewModel层数据流断裂

    • 更新的是_getProductLiveData,但Compose监听的是getProductFlow,两者未关联
    • 初始化块使用自定义CoroutineScope,存在内存泄漏风险,应使用viewModelScope
    • getProduct函数作为suspend却内部嵌套launch,逻辑冗余
  3. Model层序列化缺失

    • Product数据类无默认参数或无参构造函数,Firestore无法完成文档到对象的序列化

修正后的代码

1. Product Model(添加默认参数支持序列化)

data class Product(
    val productId: String = "",
    val title: String = "",
    val description: String = "",
    val price: Int = 0,
    val image: Int? = null,
    val category: String = "",
    val isPopular: Boolean = false,
)

2. Repository实现(改用协程await()获取集合数据)

override suspend fun getProducts(): List<Product> = withContext(Dispatchers.IO) {
    return@withContext try {
        // 获取Products集合下所有文档快照
        val collectionSnapshot = firestore.collection("Products").get().await()
        // 将快照批量转为Product对象列表
        collectionSnapshot.toObjects(Product::class.java)
    } catch (e: Exception) {
        e.printStackTrace()
        emptyList()
    }
}

3. ViewModel代码(修正数据流与协程使用)

private val _getProductFlow = MutableStateFlow<List<Product>>(emptyList())
val getProductFlow: StateFlow<List<Product>> = _getProductFlow

// 启动协程获取数据并更新Flow
fun fetchProducts() {
    viewModelScope.launch {
        val products = fireRepository.getProducts()
        _getProductFlow.value = products
    }
}

// 初始化时触发数据获取
init {
    fetchProducts()
}

4. Composable函数(使用生命周期安全的状态收集)

// 用collectAsStateWithLifecycle确保组件生命周期内的状态安全
val pro by viewModel.getProductFlow.collectAsStateWithLifecycle()

Card(
    modifier = Modifier.fillMaxWidth(),
    shape = RoundedCornerShape(15.dp),
    elevation = CardDefaults.cardElevation(
        defaultElevation = 4.dp,
        hoveredElevation = 8.dp
    )
) {
    pro.forEach {
        Text(text = it.title, color = DarkTeal)
    }
}

内容的提问来源于stack exchange,提问作者Fai Zan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 19:40:13