我如何为firestore文档设置一个监听器?

问题描述 投票:0回答:1

我正在用Ionic和react做一个聊天,使用firestore作为我的数据库。我把所有的消息都存储在一个数组中。[] 在firestore的一个文档中。并且简单的希望两个用户都能在添加消息时再次获取数据。所以我基本上想在我的文档中添加一个监听器。我的聊天器可以工作,但是你必须重新加载页面才能看到新的消息...... 这是我的代码。

const [chats, setChats] = useState([]);

    db.collection("chats").doc(chatId).onSnapshot((doc) => {

                setChats(doc.data().messages)

            });

我要么得到无限循环,要么doc.data()没有定义。有什么好办法可以用这个函数来获取数据吗?或者你需要例如firebase cloud函数?

reactjs ionic-framework google-cloud-firestore listener
1个回答
1
投票

实际上,你从文档中分享的那段代码建立了一个数据库变化的监听器,所以你不需要任何无限循环。

引用这个 实时更新文件.

使用你提供的回调进行初始调用,立即创建一个文档快照,其中包含单个文档的当前内容。然后,每当内容发生变化时,另一个调用就会更新文档快照。

所以每次发送新消息时。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。


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 未定义。

© www.soinside.com 2019 - 2024. All rights reserved.