在收听集合并向其推送更改时处理无限循环

Deal with infinite loop when listeing to a collection and pushing changes to it

我在此示例中使用 @angular/fire,但该问题对任何 firebase 连接都有效。

获取数据

 this.afs.collection<Message>('messages' , ref =>
            ref.where('chatId', '==', chatId)
 )
 .valueChanges()
 .subscribe(msgs => {

            this.removeUserFromUnseen(msgs)

      });

将更改应用于结果中的同一集合

public removeUserFromUnseen(msgs: Message[]) {
    let batch = this.afs.firestore.batch();

    msgs.forEach(msg => {
        const mesagesRef = this.afs.collection<Message>('messages').doc(msg.id).ref;
        batch.update(mesagesRef , {notSeenBy : msg.notSeenBy.filter(userId => userId !== someId )});
    });

   return batch.commit();
}

当然,这会创建一个无限循环,因为我会监听“消息”集合的更改,然后将更改应用到它。 我不想.unsubscribe使用.take或任何类似的所以我不认为这是一个重复的问题。

如何在不创建循环的情况下执行此操作?

我可以只订阅新条目或特定 属性 的更改吗?我应该重新考虑数据库的设计吗?

我正在使用 firestore

不要使用 Listeners 的结果来更改正在观看的文档!也就是说,根据定义,无限循环。

Firestore 的侦听器旨在支持客户端 应用程序:使客户端的数据displayed/available 保持最新。 假定 更改是由某种形式的用户输入触发的 - 在这种情况下,触发文档更改的是 user 操作,而不是更新。

IF 您试图做的是使用浏览器计算能力进行通用数据库处理……好吧……不要。这就是服务器和云功能的用途 - 通常,监听器对服务器和云功能没有用(服务器更有可能使用监听器,但仍然不是一个好主意。云功能是有时间限制的,所以监听器是只是没那么有用。

最后,如果您将需要更新的数据存储在与正在更新的文档相同的文档中,请重新考虑您的架构并将其分离到不同的文档或集合中。如果它们必须(“必须”)在同一文档中,请在最初更新文档的同一操作中进行更改。