Firestore保存用户选择时间列表为空问题求助
问题分析与解决方案
根据你提供的代码和描述,日志显示placeInfo包含时间数据,但Firestore中availableTimes字段为空数组,核心问题出在Firestore写入环节的实现方式上,以下是具体排查和修复方案:
关键问题点
- 不必要的
SetOptions.merge():你是创建全新文档,merge选项会在文档不存在时自动创建文档,但可能导致字段序列化时的意外行为,尤其是数组类型。 - 异步回调未等待完成:使用
addOnSuccessListener的回调模式,没有挂起等待Firestore写入完成,虽然不会直接导致数组为空,但容易出现状态同步问题。 - 手动构建Map易出错:手动将
PlaceData转成Map的方式,不如直接传入Data Class让Firestore自动序列化可靠。
修复步骤
1. 重构仓库层Firestore写入逻辑
将回调式写入改为挂起函数等待完成,移除merge选项,直接传入PlaceData对象:
override suspend fun addPlace(placeData: PlaceData): Flow<RootResult<Boolean>> = flow { emit(RootResult.Loading) try { val currentUser = firebaseAuth.currentUser val userId = currentUser?.uid if (userId != null) { // 获取新文档引用(直接生成ID并关联引用) val placeRef = firestore.collection("users") .document(userId) .collection("places") .document() val placeId = placeRef.id // 补充文档ID到PlaceData val placeToSave = placeData.copy(id = placeId) Log.d("FirestoreSave", "Saving place: $placeToSave") // 挂起等待写入完成 placeRef.set(placeToSave).await() Log.d("FirestoreSave", "Place saved successfully!") emit(RootResult.Success(true)) } else { emit(RootResult.Error("User ID is null")) } } catch (e: Exception) { Log.e("FirestoreSave", "Failed to save place: ", e) emit(RootResult.Error(e.message ?: "Something went wrong")) } }.flowOn(Dispatchers.IO)
2. 验证UI层数据收集逻辑
虽然你提到日志显示availableTimes有数据,但可以简化时间选择回调的冗余代码(不影响功能,但更简洁):
// 时间选择回调简化 val timePicker = TimePickerDialog( context, { _, hour, minute -> val selectedTime = String.format("%02d:%02d", hour, minute) availableTimes.add(selectedTime) timePickerDialog.value = false Log.d("AvailableTimes", availableTimes.toString()) }, 24, 0, true )
3. 额外检查项
- 确认Firestore规则允许写入数组类型字段,例如规则中没有限制
availableTimes的类型。 - 查看
Log.d("PlaceData", "Saving PlaceData: $placeData")的输出,确保availableTimes确实包含用户选择的时间数据。
内容的提问来源于stack exchange,提问作者ponyboyltc
相关产品推荐
相关产品推荐

