我正在将一些数据存储在Firestore中,这些数据会在我的android应用启动时加载。我使用以下方法在应用程序启动时加载此数据。
FirebaseFirestore.getInstance().collection("users").document(ApplicationEx.getUserId()).collection("items").addSnapshotListener((queryDocumentSnapshots, e) -> {
if (queryDocumentSnapshots != null) {
LOGGER.info("items fetched. from cache: " + queryDocumentSnapshots.getMetadata().isFromCache());
for (QueryDocumentSnapshot queryDocumentSnapshot : queryDocumentSnapshots) {
items.add(queryDocumentSnapshot.toObject(Item.class));
}
}
});
当我重新启动应用程序时,可以看到数据是从缓存中获取的,因为queryDocumentSnapshots.getMetadata().isFromCache()
每次都返回true。但是,当我检查Firebase控制台时,可以看到有时文档读取计数增加。
该行为不一致。当我连续多次重新启动应用程序时,大多数情况下读取计数不会增加。但是,如果我有几分钟没有使用该应用程序,然后启动该应用程序,则读取计数通常会增加。
存储的数据不会更改,因此这不可能是由于android同步更改的数据。
这可能是什么原因?
答案 0 :(得分:0)
最低查询费用
您每次查询至少要读取一份文档 执行,即使查询没有返回结果。
因此,如果查询命中服务器,则会至少读取一次。
此外,在“收听查询结果”部分:
如果收听者断开连接的时间超过30分钟(例如, 如果用户离线),您将被收取阅读费用,就像您有 发出了全新的查询。
这意味着,如果您的听众离开并在30分钟后返回(例如,如果该应用程序已后台运行且稍后又前台运行),那么您将再次为查询付费。
如果您的帐单未正确加起来,并且有一个可重现的示例,任何人都可以运行,则应contact Firebase support directly并提供这些详细信息。
答案 1 :(得分:0)
我联系了Firebase支持人员,根据他们的说法,这就是它在Firestore中的工作方式。即使将项目本地缓存,当侦听器断开连接超过30分钟时,下一次读取也会从服务器读取所有文档。
我使用以下机制在某种程度上克服了我的问题。
编写一个新的firebase云功能,以侦听集合的写入。它会将集合更新到实时数据库的时间写入。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.onItemModified = functions.firestore.document('users/{userId}/items/{itemId}').onWrite((change, context) => {
return admin.database().ref('/users/' + context.params.userId + '/items-updated-at').set(Date.now());
});
在android中,在应用启动时,禁用网络,加载项目,然后再次启用网络。
FirebaseFirestore.getInstance().disableNetwork().addOnCompleteListener(task -> loadItems());
private void loadItems() {
Utils.getFirestoreCollection(COLLECTION_NAME_ITEMS).get().addOnCompleteListener(task -> {
//Cache loaded items in memory
FirebaseFirestore.getInstance().enableNetwork();
}
}
在android中,将侦听器添加到写入最后一项更新时间的实时数据库路径。触发更新事件时,请再次读取项目并更新内存缓存。将项目更新时间存储在android共享的首选项中,以便在下次更新事件触发时,检查RTDB的更新时间是否高于保存的时间,并且仅在RTDB更新时间高于保存的时间时再次读取项目。>