创建Firestore文档时能否直接获取creationTime,避免后续读取操作?
能否在创建Firestore文档时直接通过DocumentRef获取serverTimestamp生成的creationTime?
很遗憾,没办法直接通过newDocumentRef获取到服务器生成的creationTime,核心原因在于FieldValue.serverTimestamp()的工作机制:
当你调用collectionRef.add()传入serverTimestamp()时,这个值只是一个客户端的占位符,Firestore服务器在接收创建请求后,才会将这个占位符替换成实际的服务器时间戳并写入文档。而add()方法返回的DocumentRef只是指向这个新文档的引用,它本身并不包含文档的实际数据——包括服务器生成的时间戳,因为此时服务器可能还没完成时间戳的生成和文档的最终写入。
替代方案
如果想避免后续的读取操作,可以根据你的需求选择以下两种方式:
1. 客户端生成时间戳(简单快捷)
如果你的场景不需要严格依赖Firestore服务器的时间(比如用户设备时间误差可以接受),可以直接在客户端生成时间戳,这样创建文档时就能立刻拿到这个值:
// 生成客户端时间戳(和服务器时间逻辑一致的Timestamp类型) const clientCreationTime = firebase.firestore.Timestamp.now(); const newDocumentRef = await collectionRef.add({ ...newDocumentData, creationTime: clientCreationTime }); // 直接使用预先生成的clientCreationTime,无需额外读取 console.log("文档创建时间:", clientCreationTime.toDate());
注意:这种方式的缺点是如果用户设备时间不准确,会导致时间戳有偏差。
2. 接受一次轻量的读取操作(严格服务器时间)
如果必须使用Firestore服务器的时间,那么后续的读取操作其实开销非常小——Firestore会优先从本地缓存读取刚创建的文档,速度很快,代码逻辑也清晰:
const newDocumentRef = await collectionRef.add({ ...newDocumentData, creationTime: firebase.firestore.FieldValue.serverTimestamp() }); // 读取文档获取服务器时间戳 const document = await newDocumentRef.get(); if (document.exists) { const documentData = document.data(); console.log("服务器生成的创建时间:", documentData.creationTime.toDate()); }
总结
- 要即时获取时间戳且能接受客户端时间:用客户端生成的
Timestamp.now() - 必须用服务器时间:只能通过后续读取文档获取,这个操作的成本几乎可以忽略
内容的提问来源于stack exchange,提问作者eosca
相关产品推荐
相关产品推荐

