首页 > 解决方案 > Firestore onSnaphot 返回重复数据

问题描述

当我从 Firestore 收听数据更改时,我会在数组中获取先前的更改和新的更改。如何仅检索新的更改而没有重复项?下面的代码在 useEffect()

     await db.collection("Recent").where("members", "array-contains", currentUser.uid)
        .onSnapshot(snapshot => {
            setChatList([])
            setChatList(snapshot.docs.map(doc => doc.data()))
        })

标签: javascriptreactjsfirebasegoogle-cloud-firestore

解决方案


如果您在数据库上使用 set 或 update,这是预期行为,因为 onSnapshot 会对缓存写入和同步操作做出反应。

在同步任何更改之前,它处于挂起状态:

使用新数据立即触发更改事件。该文档尚未写入后端,因此“待写入”标志为真。文档被写入后端。后端通知客户端写入成功。文档数据没有变化,但元数据发生了变化,因为“等待写入”标志现在为假。

此外:

每次查询结果更改时(即添加、删除或修改文档时),快照处理程序都会收到一个新的查询快照。因为您在没有任何过滤器的情况下调用查询条件,所以 onSnapshot 是一个侦听器,它将返回已删除的数据以及新的数据。您必须过滤列表中的文档或在 useEffect 之外管理侦听器 * 。

因此,我强烈建议将您的 onSnapshot 修改为在 useEffect 之外并在可以适当反应或get()用作替代方案的专用函数中。

否则,提供的示例适用于验证更改元

db.collection("cities").where("state", "==", "CA")
    .onSnapshot((snapshot) => {
        snapshot.docChanges().forEach((change) => {
            if (change.type === "added") {
                console.log("New city: ", change.doc.data());
            }
            if (change.type === "modified") {
                console.log("Modified city: ", change.doc.data());
            }
            if (change.type === "removed") {
                console.log("Removed city: ", change.doc.data());
            }
        });
    });

资料来源:https ://firebase.google.com/docs/firestore/query-data/listen


推荐阅读