如何设置Firestore文档的侦听器?

时间:2020-05-03 21:12:05

标签: reactjs ionic-framework google-cloud-firestore listener

我正在与Ionic聊天,并使用Firestore作为数据库进行响应。我将所有消息存储在Firestore中的文档中的数组[]中。并且只是希望两个用户都可以在添加消息后再次获取数据。所以我基本上想在我的文档中添加一个侦听器。我的聊天正在进行,但您必须重新加载页面才能查看新消息...这是我的代码:

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

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

                setChats(doc.data().messages)

            });

我遇到无限循环或doc.data()未定义。是否有使用此功能获取数据的好方法?还是需要例如Firebase云功能?

2 个答案:

答案 0 :(得分:1)

实际上,您从文档中共享的代码段建立了一个监听器,可以监听数据库中的更改,因此您不需要任何无限循环。

为此documentation for realtime updates报价。

使用您提供的回调进行的初始调用会立即使用单个文档的当前内容创建一个文档快照。然后,每次内容更改时,另一个调用都会更新文档快照。

因此,每次发送新消息时,都会触发onSnapshot。您可以在提供的回调中引用snapshot而不是doc,然后可以使用snapshot.docChanges()查看发生了什么变化。这是一个示例:

db.collection("chats").doc(chatId)
    .onSnapshot(function(snapshot) {
        if(snapshot.docChanges().length > 0){
            //do something
        }
    });

注意:如果这是第一个快照,则所有数据将作为已添加的更改出现在列表中,您可以通过逐个获取每个更改并引用其数据来获取数据:{{1 }}。另外,由于您要通过change.doc().data()查询,因此数组的大小应始终为1。

答案 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未定义的问题。