与.limitToLast一起使用时,如何仅使用.onSnapshot从Firebase获取新文档

时间:2020-08-17 13:36:11

标签: firebase pagination infinite-scroll

我正在尝试使用Firebase无限滚动地实现聊天应用程序。问题是,如果在添加新消息时不清空消息数组,则它们将重复。如果我清空messages数组,则不会保留先前的消息。

代码如下:

  getAllMessages(matchId: string) {
    this.chatSvc.getAllMessages(matchId)
      .orderBy('createdAt', 'asc')
      .limitToLast(5)
      .onSnapshot((doc) => {
        if (!doc.empty) {
          this.messages = [];
          doc.forEach((snap) => {
            this.messages.push({
              content: snap.data().content,
              createdAt: snap.data().createdAt,
              sendingUserId: snap.data().sendingUserId,
              receivingUserId: snap.data().receivingUserId
            });
          });
        } else {
          this.messages = [];
        }
      });
  }
和返回引用的聊天服务:

  getAllMessages(matchId: string): firebase.firestore.CollectionReference<firebase.firestore.DocumentData> {
    return firebase
    .firestore()
    .collection(`matches`)
    .doc(`${matchId}`)
    .collection('messages');

  }

我正在将来自集合的消息推送到message数组中。如果我不添加'this.messages = []',则每次在集合中添加新消息时,它都会复制一条消息。

如何仅使用onSnapshot从Firebase获取新文档,而不是再次遍历所有集合?我只想要最后一条消息,因为我将使用另一个检索先前消息的查询来实现无限滚动。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

只要符合条件的新条目出现,查询将始终返回最后5个结果,这将创建重复项。您可以做的是listen to changes between snapshots

getAllMessages(matchId: string) {
    this.chatSvc.getAllMessages(matchId)
      .orderBy('createdAt', 'asc')
      .limitToLast(5)
      .onSnapshot((snapshot) => {
        snapshot.docChanges().forEach((change) => {
          // push only new documents that were added
          if(change.type === 'added'){
           this.messages.push(change.doc.data());
          }
        });
      });
  }