Reactjs 如何设置firestore文档的侦听器?

Reactjs 如何设置firestore文档的侦听器?,reactjs,ionic-framework,google-cloud-firestore,listener,Reactjs,Ionic Framework,Google Cloud Firestore,Listener,我正在与Ionic聊天,并使用firestore作为我的数据库。我将所有消息存储在firestore的一个文档中的一个数组中。如果添加了消息,只需让两个用户再次获取数据。所以我基本上想在我的文档中添加一个侦听器。我的聊天功能正常,但您必须重新加载页面才能看到新消息。。。这是我的代码: const [chats, setChats] = useState([]); db.collection("chats").doc(chatId).onSnapshot((doc) => {

我正在与Ionic聊天,并使用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);
    }
当我把监听器放在
useffect()
hook中时,我用无限循环解决了这个问题,因为每次监听器内部的状态更新时,新的监听器都会启动。现在,在安装组件时,侦听器只初始化一次


通过向函数发送
snapshot.data()
,然后获取
data.messages
,我解决了
snapshot.data().messages
未定义的问题。

您目前共享的代码既不会导致无限循环,也不会引用
doc.data
。请确保您的问题包括(请阅读链接,因为它包含了更多关于如何最大限度地利用他人帮助机会的提示)。谢谢您的回答!这是我第一次使用Firebase Firestore,所以我没有意识到“onSnapshot()”设置了一个侦听器。但我明白了为什么我得到了一个无限循环,因为我试图在监听器中使用“setState”。这将触发重新渲染并设置新的侦听器。所以我将“onSnapshot()-listener”放在“useffect()”钩子中,这样它在安装组件时只触发一次。我可以在数据更新时检索新数据。我意识到我的问题格式不好,因为没有提到setState问题。但是我的聊天功能正在运行,所以谢谢你的帮助!是的,我会更新我的问题并回答它!我已经给你的答案投了赞成票,但由于om未满15岁,所以没有公开显示。