我正在用Ionic和react做一个聊天,使用firestore作为我的数据库。我把所有的消息都存储在一个数组中。[]
在firestore的一个文档中。并且简单的希望两个用户都能在添加消息时再次获取数据。所以我基本上想在我的文档中添加一个监听器。我的聊天器可以工作,但是你必须重新加载页面才能看到新的消息...... 这是我的代码。
const [chats, setChats] = useState([]);
db.collection("chats").doc(chatId).onSnapshot((doc) => {
setChats(doc.data().messages)
});
我要么得到无限循环,要么doc.data()没有定义。有什么好办法可以用这个函数来获取数据吗?或者你需要例如firebase cloud函数?
实际上,你从文档中分享的那段代码建立了一个数据库变化的监听器,所以你不需要任何无限循环。
引用这个 实时更新文件.
使用你提供的回调进行初始调用,立即创建一个文档快照,其中包含单个文档的当前内容。然后,每当内容发生变化时,另一个调用就会更新文档快照。
所以每次发送新消息时。onSnapshot
将被触发。您可以参考 snapshot
而不是 doc
的回调,然后您可以使用 snapshot.docChanges()
看看有什么变化。下面是一个例子。
db.collection("chats").doc(chatId)
.onSnapshot(function(snapshot) {
if(snapshot.docChanges().length > 0){
//do something
}
});
注: 如果这是第一个快照,所有的数据都会在列表中作为添加的更改,你可以通过单独提取每个更改并引用它的数据来获取数据。change.doc().data()
. 另外,由于你是通过 chatId
,数组的大小应该始终为1。
我用这种方法解决了我的问题。
const [chats, setChats] = useState([]);
useEffect(() => {
db.collection("chats").doc(chatId).onSnapshot(snapshot => {
updateMessages(snapshot.data())
})
}, []);
function updateMessages(data : any) {
setChats(data.messages);
}
当我把监听器放在一个 useEffect()
钩子,我解决了无限循环的问题,因为每次在监听器内更新状态时都会启动一个新的监听器。现在监听器只在组件被挂载时初始化一次。
而且通过发送 snapshot.data()
到一个函数,然后获取 data.messages
我解决了这个问题与 snapshot.data().messages
未定义。