Android(Kotlin+Jetpack Compose)从Firebase Firestore取数得空列表
解决Firestore获取数据返回空列表的问题
问题场景
使用Android(Kotlin+Jetpack Compose)从Firebase Firestore获取数据时,始终得到长度为0的列表,但数据库中实际存在数据。以下是问题代码的错误排查及修正方案:
原代码核心问题
Repository层逻辑错误
- 调用
document("")指定了空文档ID,实际需要获取整个Products集合的数据,而非单个空文档 - 混用Firestore回调API与协程
suspend函数,导致协程无法正确返回数据,ViewModel拿不到有效结果 - 返回类型
Any过于宽泛,不符合业务逻辑
- 调用
ViewModel层数据流断裂
- 更新的是
_getProductLiveData,但Compose监听的是getProductFlow,两者未关联 - 初始化块使用自定义
CoroutineScope,存在内存泄漏风险,应使用viewModelScope getProduct函数作为suspend却内部嵌套launch,逻辑冗余
- 更新的是
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
相关产品推荐
相关产品推荐

