Firestore以时间戳为键存储数据出现嵌套层级的原因与解决方案
问题原因
你代码里用DateTime.now().toString()生成的键包含小数点(.),比如格式类似2024-05-20 14:35:22.456789。Firestore会将字段名中的.解析为嵌套字段的路径分隔符,所以它不会把这个完整字符串当作单个键,而是创建名为2024-05-20 14:35:22的父对象,再在其中创建456789子字段存储值,最终形成截图里的嵌套结构。
解决方法
需要生成不含小数点的时间戳字符串作为键,或替换掉小数点,以下是几种可行方案:
方案1:去掉毫秒部分,保留年月日时分秒
修改时间戳格式,剔除毫秒:
await FirebaseFirestore.instance .collection("users") .doc(uid) .collection('data') .doc(device.id) .update({ DateTime.now().toIso8601String().split('.').first: "${result['humidity']}_${result['tempInC']}" });
生成的键格式类似2024-05-20T14:35:22,无小数点,会被Firestore识别为单个字段键。
方案2:替换小数点为下划线
保留毫秒信息的同时替换小数点:
final timestampKey = DateTime.now().toString().replaceAll('.', '_'); await FirebaseFirestore.instance .collection("users") .doc(uid) .collection('data') .doc(device.id) .update({ timestampKey: "${result['humidity']}_${result['tempInC']}" });
生成的键格式类似2024-05-20 14:35:22_456789,属于合法的单个字段键。
方案3:使用Firestore原生Timestamp生成键
借助Firestore自带的Timestamp类型生成字符串,规避格式问题:
// 保留毫秒并替换小数点 final timestampKey = Timestamp.now().toString().replaceAll('.', '_'); // 或者仅用秒级时间戳(无需毫秒时) // final timestampKey = Timestamp.now().seconds.toString(); await FirebaseFirestore.instance .collection("users") .doc(uid) .collection('data') .doc(device.id) .update({ timestampKey: "${result['humidity']}_${result['tempInC']}" });
注意:如果文档中已存在之前生成的嵌套结构字段,需手动删除旧数据,避免残留结构影响后续存储。
内容的提问来源于stack exchange,提问作者Abdullah Saeed
相关产品推荐
相关产品推荐

