Javascript 使用Firebase的Firestore高效(持续)更新聊天信息

Javascript 使用Firebase的Firestore高效(持续)更新聊天信息,javascript,firebase,react-native,google-cloud-firestore,Javascript,Firebase,React Native,Google Cloud Firestore,我正在开发一个React本机应用程序,它使用Firebase的Firestore作为后端。现在,每次新消息出现时,我都会从Firestore获取所有消息并更新我的状态,尽管只出现一条新消息 function listenCurrentChat(dispatch, chatID) { const address = "chats/" + chatID + "/messages"; firebase.firestore().collection(address).orderBy('c

我正在开发一个React本机应用程序,它使用Firebase的Firestore作为后端。现在,每次新消息出现时,我都会从Firestore获取所有消息并更新我的状态,尽管只出现一条新消息

function listenCurrentChat(dispatch, chatID) {
    const address = "chats/" + chatID + "/messages";
    firebase.firestore().collection(address).orderBy('createdAt')
        .onSnapshot(function (querySnapshot) {
            dispatch({
                type: CLEAR_MESSAGES,
                payload: {
                    chatID: chatID,
                }
            });
            querySnapshot.forEach(function (doc) {
                //local
                if (doc.metadata.hasPendingWrites) {
                    dispatch({
                        type: ADD_MESSAGE,
                        payload: {
                            chatID: chatID,
                            message: {...doc.data(), createdAt: new Date()}
                        }
                    });
                } else {
                    dispatch({
                        type: ADD_MESSAGE,
                        payload: {
                            chatID: chatID,
                            message: {...doc.data(), createdAt: doc.data().createdAt.toDate()}
                        }
                    });
                }
            });
        });
}
显然,这是非常糟糕的,因为我只对一条新消息使用了多次读取,而且用户体验根本不好,因为存在持续的延迟。我还尝试在redux状态下保存这些实时侦听器的地址,并从最后一条消息的时间戳中进行侦听,但这似乎也不是一个好的解决方案,因为我不再考虑以前的消息可以编辑的事实。在React本机部分更新聊天对话的好方法是什么,这样我就可以使用尽可能少的Firestore阅读


提前感谢。

在我看来,您的代码在查询中添加了一个侦听器,每次查询结果更改时都会调用该侦听器

听起来你好像在想,每次都会重新阅读每个文档。Firestore侦听器不是这样工作的。只要附加了该侦听器,它将只读取对该查询的更改,而不是整个查询结果。该查询中任何未更改的文档都不会被重新读取,即使您观察到它会被重新传递给侦听器。Firebase SDK会在连接侦听器的时间内将所有文档缓存在内存中,并且只读取与服务器保持同步所需的最少数量的文档


换句话说,它已经使用了最少的读取次数。

在我看来,您的代码在一个查询上添加了一个侦听器,每当这些结果发生变化时,该侦听器就会被查询结果调用

听起来你好像在想,每次都会重新阅读每个文档。Firestore侦听器不是这样工作的。只要附加了该侦听器,它将只读取对该查询的更改,而不是整个查询结果。该查询中任何未更改的文档都不会被重新读取,即使您观察到它会被重新传递给侦听器。Firebase SDK会在连接侦听器的时间内将所有文档缓存在内存中,并且只读取与服务器保持同步所需的最少数量的文档


换句话说,它已经在使用最小的读取次数。

问题在于,每次添加新消息时,侦听器都会返回所有元素,如果新消息是新的或已经存在,则继续检查新消息是无效的。如果您只想知道自上次调用侦听器以来发生了哪些更改,使用querySnapshot.docChanges只能查看添加、更改和删除的文档。处理此数据不会引起任何额外的读取-所有数据都已经是本地数据。另请参见。问题在于,每次添加新消息时,侦听器都会返回所有元素,如果新消息是新的或已经存在,则不必继续检查任何新消息。如果您只想知道自上次调用侦听器以来发生了哪些更改,则只能查看添加的、更改的、更改的消息,并使用querySnapshot.docChanges删除文档。处理此数据不会引起任何额外的读取-所有数据都已经是本地数据。另见。