如何在 Firestore 的实时群聊中处理数千条消息?

How to handle thousands of messages in a real-time group chat with Firestore?

我需要一些有关 Firestore 构建聊天应用的帮助。我查看了 documentation,但找不到我需要的答案。

我正在构建一个必须处理数千条消息的实时聊天(多对多),并且还可以编辑、删除和取消删除这些消息。 主要问题是一次加载所有消息(如 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 处理大量消息,您有什么建议吗?我的分页方法有什么错误吗?或者这是错误的方法?

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

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

有更多这样的边缘情况,这是 FirestorePagingAdapter in FirebaseUI 不处理实时更新的原因之一。