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

Firestore保存用户选择时间列表为空问题求助

问题分析与解决方案

根据你提供的代码和描述,日志显示placeInfo包含时间数据,但Firestore中availableTimes字段为空数组,核心问题出在Firestore写入环节的实现方式上,以下是具体排查和修复方案:

关键问题点

  1. 不必要的SetOptions.merge():你是创建全新文档,merge选项会在文档不存在时自动创建文档,但可能导致字段序列化时的意外行为,尤其是数组类型。
  2. 异步回调未等待完成:使用addOnSuccessListener的回调模式,没有挂起等待Firestore写入完成,虽然不会直接导致数组为空,但容易出现状态同步问题。
  3. 手动构建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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:05:55