我正在为我的 Flutter/Firebase 项目实现缓存。对于常规文档
get
,我经常这样做:
DocumentSnapshot<Map<String, dynamic>> doc;
try {
doc = await storeRef.doc(uid).get(GetOptions(source: Source.cache));
} catch (_) {
doc = await storeRef.doc(uid).get(GetOptions(source: Source.server));
}
效果很好,并且按预期完成了工作。然而,当我对我的一些
collectionGroup
尝试同样的方法时,它并没有按预期工作。 collectionGroup
结果仅包含已缓存的项目,而不是整个 collectionGroup
。
我的代码如下:
// caching doesn't work with collectionGroup
QuerySnapshot<Map<String, dynamic>> query;
try {
query = await FirebaseFirestore.instance.collectionGroup("users").where('uid', isEqualTo: uid).get(GetOptions(source: Source.cache));
} catch (_) {
query = await FirebaseFirestore.instance.collectionGroup("users").where('uid', isEqualTo: uid).get(GetOptions(source: Source.server));
}
这是有道理的,但只是想看看是否有人找到了解决办法,让它在第一个
get
之后缓存值,而不是每次都从firestore中提取,这是昂贵的,因为这个特定的查询在我的整个过程中经常使用项目。
如果不起作用,我可能会在第一个
get
之后使用本地地图作为短期缓存,虽然这可能不是很高效或优化,但它会显着减少从firestore的读取并节省成本。
你说:
collectionGroup 结果将仅包含已缓存的项目,而不是整个 collectionGroup。
这是有道理的。由于您告诉 Firestore 从本地缓存获取查询结果,因此它返回的都是本地缓存的结果。
如果您希望它从服务器检索最新结果,您应该停止告诉它仅从本地缓存返回结果。那时,您将为服务器上的文档读取付费,因为 Firestore 确定文档是否已更改的唯一方法是实际读取它。
不过,您的应用程序可能会做得更好。例如,我经常:
lastUpdated
字段,我在每次写入时都设置该字段。这会使代码变得复杂,但会节省您想要避免的文档读取。