如何正确使用 Firestore 的 serverTimestamp 来设置正在订阅的文档的值?
2020-08-20
891
概述/环境:
- react-native 项目 v0.61.5
-
使用
react-native-firebase
包 - 使用操作填充 redux 状态,通过 props 显示 firestore 数据
目标:
- 监听文档集合
-
使用 Firestore 的
FieldValue.serverTimestamp()
设置所述集合中文档的时间值 -
在快照监听器中使用 serverTimestamp 的
toMillis()
函数
观察/错误:
- 在所述集合中创建文档时,文档创建正常,显示正常
-
在创建文档/时间值时,应用程序因调用
doc.get('time').toMillis()
位于快照侦听器内:TypeError: null 不是对象(评估“doc.get('time').toMillis()”)
到目前为止,我已经尝试了此处提到的所有建议: 为什么 Firestore 的“doc.get('time').toMillis”会产生 null 类型错误?
似乎没有什么可以解决这个问题崩溃。
这是快照监听器:
.onSnapshot({ includeMetadataChanges: true }, (querySnapshot) => {
if (querySnapshot.metadata.fromCache && querySnapshot.metadata.hasPendingWrites) {
// ignore cache snapshots where new data is being written
return;
}
const messages = [];
querySnapshot.forEach((doc) => {
const estimateTimestamps = { serverTimestamps: 'estimate' }
const msg = doc.data();
msg.docId = doc.id;
msg.time = doc.get('time', estimateTimestamps).toMillis();
const timestamp = doc.get('time', estimateTimestamps);
if (timestamp) {
msg.time = timestamp.toMillis();
} else {
debugger
console.error(doc.id + ' is missing "time" field!');
}
messages.push(msg);
});
dispatch({ type: types.LOAD_MSGS, payload: messages });
resolve();
});
这是文档的创建方式:
const addMsg = (msg, userConvos) => {
return firebase.firestore().collection('messages').add({
time: firebase.firestore.FieldValue.serverTimestamp(),
sender: msg.sender,
read: false,
userConvos: [userConvos.sender, userConvos.receiver],
content: {
type: 'msg',
data: msg.text
}
});
};
我理解该值在短时间内可能为空,我需要一种方法来防止应用程序在此期间崩溃。
2个回答
错误将您指向此代码:
doc.get('time').toMillis()
它表示
doc.get('time')
返回 null,因此您无法对其调用
toMillis()
。
您链接到的问题的答案确切解释了原因。如果仍然不清楚,我建议再读一遍。如果服务器时间戳事件未到达服务器,则时间戳将为 null。
也许您想像这样检查时间戳是否为 null,而不调用
toMillis()
:
msg.isPending = doc.get('time') === null;
Doug Stevenson
2020-08-20
在 @DougStevenson 帮助我理解之后。有点令人困惑,但重要的是要理解侦听器一直在运行,因此一旦时间值可用,它就会被设置,因此不存在真正的性能问题。我重新制定了我的方法,它有效:
querySnapshot.forEach((doc) => {
const estimateTimestamps = { serverTimestamps: 'estimate' }
const msg = doc.data();
msg.docId = doc.id;
msg.time = doc.get('time', estimateTimestamps).toMillis();
const timestamp = doc.get('time', estimateTimestamps)
if (doc.get('time') !== null) {
msg.time = doc.get('time').toMillis()
}
messages.push(msg);
});
Jim
2020-08-20