Flutter中如何向Firestore文档添加服务器时间戳并解决类型报错?
问题解答
- 完全可以无需转字符串,直接在Firestore中存储Timestamp类型变量。Firestore原生支持Timestamp数据类型,存储后读取时可以直接转为Dart的DateTime对象使用,相比存字符串精度更高,还支持时间排序、范围查询等原生操作,是官方推荐的时间存储方案。
- Flutter中完全支持通过
FieldValue.serverTimestamp()指示服务器自动写入时间戳,你遇到的报错不是该方法本身的问题,是代码中其他字段的类型错误引发的。
报错原因排查
你收到的「Expected a value of type 'String', but got one of type 'FieldValue'」报错和时间戳配置无关,问题出在你直接把auth.currentUser!赋值给了createdBy、updatedBy字段:auth.currentUser是User类型的对象,Firestore无法直接存储该类型,你需要取用户的具体字符串属性存储,比如用户uid、邮箱等,类型为String就符合要求,你之前误判了报错的触发源。
修正后的代码示例
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; Future<bool> addSubject(FirebaseFirestore x, FirebaseAuth auth, String subjectName) async{ try { var doc = { "subject": subjectName }; await x.collection('subjects').add(appendCreateAudit(doc, auth)); } catch (e) { print(e); return false; } return true; } Map<String, dynamic> appendCreateAudit(Map<String, dynamic> x, FirebaseAuth auth) { x["createdAt"] = FieldValue.serverTimestamp(); // 修正:存储用户uid而非整个User对象 x["createdBy"] = auth.currentUser!.uid; x["updatedAt"] = FieldValue.serverTimestamp(); x["updatedBy"] = auth.currentUser!.uid; print(x); return x; } Map<String, dynamic> appendUpdateAudit(Map<String, dynamic> x, FirebaseAuth auth) { x["updatedBy"] = auth.currentUser!.uid; x["updatedAt"] = FieldValue.serverTimestamp(); return x; }
附加说明:读取Timestamp转DateTime的方法
从Firestore读取时间字段时,调用Timestamp对象的toDate()方法即可转为Dart原生的DateTime类型:
// 假设doc是查询拿到的文档快照 DateTime createdAt = (doc["createdAt"] as Timestamp).toDate();
如果你的应用需要支持离线写入,可以在查询时配置includeMetadataChanges: true监听服务器时间回传状态,避免本地临时写入时值为null的问题。
内容的提问来源于stack exchange,提问作者NewbieCoder
相关产品推荐
相关产品推荐

