首页 > 解决方案 > 如何在与 Firestore 的实时群聊中处理数千条消息?

问题描述

我需要一些关于 Firestore 构建聊天应用程序的帮助。我查看了文档,但找不到所需的答案。

我正在构建一个必须处理数千条消息的实时聊天(多对多),并且这些消息也可以被编辑、删除和取消删除。主要问题是一次加载所有消息(如 Firebase 建议的那样)然后在前端管理它们会冻结我的前端应用程序以获取大量消息。我尝试使用分页 API 来做到这一点,但我遇到了一些极端情况,例如

let last = null;

// Execute the first query saving the last doc
const ref = db
 .collection('chat')
 .orderBy('timestamp')
 .limit(10)
 .onSnapshot(({docs}) => {
    last = docs[docs.length - 1]
   // my logic
 })

// When needed I'll execute the second query starting from the last doc
// of the previous query
const ref = db
 .collection('chat')
 .orderBy('timestamp')
 .limit(10)
 .startAfter(last)
 .onSnapshot(({docs}) => {
    last = docs[docs.length - 1]
    // my logic
 })

如果第一个查询返回的最后一个文档被删除,我只从第一个查询中获取更新,例如

[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] // original docs from the first query
[10,11,12,13,14,15,16,17,18,19] // original docs from the second query

删除文档9会触发第一个查询的更新,因此在我的前端我将10复制文档。

[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10] // updated docs from the first query
[10,11,12,13,14,15,16,17,18,19] // original docs from the second query

我猜还有其他我没有考虑过的边缘情况。您对如何使用 Firebase 处理大量消息有什么建议吗?我的分页方法有什么错误吗?或者也许这是错误的方法?

标签: firebasegoogle-cloud-firestorechat

解决方案


您的方法很好,但事实证明,使用基于光标的 API 进行分页和实时更新会导致一些棘手的边缘情况。

您必须根据ID 删除重复的文档,然后拥有不同大小的页面,或者更新第二个查询的起点(然后当您有更多页面时再进行查询)。

还有更多这样的边缘情况,这是FirestorePagingAdapterFirebaseUI中不处理实时更新的原因之一。


推荐阅读