Firestore 管理员 "listens" 重新启动时再次访问所有文档

Firestore admin "listens" to all documents again on reboot

TL;DR
每次我的 Fiestore 管理服务器重新启动时,我的文档侦听器都会为所有文档触发,即使我已经侦听并处理了文档。我该如何解决这个问题?
结束 TL;DR

我正在为我的 Firestore 聊天应用程序构建后端。基本思想是,每当用户通过客户端应用程序输入聊天消息时,后端服务器都会侦听新消息并对其进行处理。

我 运行 遇到的问题是,每当我重新启动我的应用程序服务器时,都会为所有现有的已处理聊天触发侦听器。因此,即使之前已经回复过,它也会回复每个聊天。我希望应用服务器仅响应它尚未响应的新聊天。

我的一个变通办法是在每个聊天文档上放置一个布尔标志。当后端处理聊天文档时,它会设置标志。然后,侦听器将仅回复未设置标志的聊天。

这是一种合理的方法还是有更好的方法?我担心的一个问题是,每次我重新启动我的应用程序服务器时,我都会被收取高额费用以重新查询之前的所有聊天记录。我担心的另一个问题是听力似乎受限于记忆?如果我的应用程序大规模扩展,我是否必须将所有聊天文档存储在内存中?这似乎不会很好地扩展...

    //Example listener that processes chats based on whether or not the "hasBeenRepliedTo" flag is set
    public void startFirestoreListener() {
        CollectionReference docRef = db.collection("chats");
        docRef.addSnapshotListener(new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, @javax.annotation.Nullable FirestoreException e) {
            if(e != null) {
                logger.error("There was an error listening to changes in the firestore chats collection. E: "+e.getLocalizedMessage());
                e.printStackTrace();
            }
            else if(queryDocumentSnapshots != null && !queryDocumentSnapshots.isEmpty()) {
                for(ChatDocument chatDoc : queryDocumentSnapshots.toObjects(ChatDocument.class)) {
                    if(!chatDoc.getHasBeenRepliedTo() {
                        //Do some processing
                        chatDoc.setHasBeenRepliedTo(true); //Set replied to flag
                   }
                   else {
                     //No-op, we've already replied to this chat
                   }
                }
            }
        }
    });

}

是的,为了避免每次都获取每个文档,您将必须构建一个只生成您知道已处理过的文档的查询。

不,您无需为查询文件付费。您只需阅读它们,如果您的查询产生文档,就会发生这种情况。

是的,您必须能够在内存中保存查询的所有结果。

如果您使用 Cloud Functions to receive events for each new document in a collection. You won't have to worry about any of the above things, and instead just worry about writing a Firestore trigger 来处理每个新文档并为这些调用付费,您的问题将更容易解决。