Firestore管理员在重新启动时再次“侦听”所有文档

时间:2018-03-23 23:02:09

标签: java firebase google-cloud-firestore firebase-admin

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
                   }
                }
            }
        }
    });

}

1 个答案:

答案 0 :(得分:2)

是的,为避免一直收到每个文档,您必须构建一个查询,只生成您知道已处理的文档。

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

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

如果使用Cloud Functions接收集合中每个新文档的事件,则问题将更容易解决。您不必担心上述任何事情,而只是担心编写一个Firestore trigger来为每个新文档执行您想要的操作,并为这些调用付费。