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 来处理每个新文档并为这些调用付费,您的问题将更容易解决。
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 来处理每个新文档并为这些调用付费,您的问题将更容易解决。