我知道 Firebase on Flutter 会首先自动从缓存中读取,但我在开发时注意到,一个应用程序只是玩了近 1 个流,其中包含 10 或 15 个文档,我已经达到了 4000 次以上的读取!这样,如果有 10 个用户使用过我的应用程序,我将支付我所拥有的一切,所以我重新检查了每个查询、快照并把这段代码知道
print(itemDoc.metadata.isFromCache ? "itemDoc NOT FROM NETWORK" : "itemDoc FROM NETWORK");
编辑编写代码和更多说明
我注意到当我更新,添加,删除文档控制台打印所有存储的文档时,IOS中出现了此问题。
我有主流,我得到了所有用户列表 然后我为它创建的每个列表都流以收听列表的项目
userListsStream(uid){
Stream<QuerySnapshot> shoppingListsStream =
Firestore.instance.collection('lists').where('owner', arrayContains: uid).snapshots();
shoppingListsStream.listen(
(QuerySnapshot listsQuery) async {
List<DocumentSnapshot> listsDocs = listsQuery.documents;
if (listsDocs.length != 0) {
//? foreach on lists Documents
listsDocs.forEach(
(DocumentSnapshot listDoc) async {
print(listDoc.metadata.isFromCache ? "listDoc NOT FROM
NETWORK" : "listDoc FROM NETWORK");
listItemsStream(listDoc.documentID);
}
)
}
})
}
listItemsStream(lid){
shoppingItemsRef = Firestore.instance.collection('lists').document(lid).collection('items');
shoppingItemsRef.snapshots().listen(
(QuerySnapshot itemsQuery) async {
List<DocumentSnapshot> itemsDocs = itemsQuery.documents;
if (itemsDocs.length != 0) {
itemsDocs.forEach(
(DocumentSnapshot itemDoc) async {
print(itemDoc.metadata.isFromCache ? "itemDoc NOT FROM
NETWORK" : "itemDoc FROM NETWORK");
}
)
}
}
我在Provider
中调用 main 函数的这两个方法Home.dart
initState
@override
void initState() {
Provider.of<ListsProvider>(context, listen: false)
.userListsStream(uid);
}
isFromCache
标志指示文档是否保证与服务器保持最新,或者它可能是缓存中的过时结果。如果是false
,这并不一定意味着文档是从服务器读取的,但可以保证文档是服务器最新的。
为了说明这意味着什么,我可以
var snapshotsStream = Firestore.instance.collection("chat").orderBy("timestamp", descending: true).limit(3).snapshots();
snapshotsStream.listen((querySnapshot) {
print("We got a new QuerySnapshot");
querySnapshot.documents.forEach((doc) {
print(doc.documentID+": "+(doc.metadata.isFromCache ? "from CACHE " : "from SERVER "));
});
querySnapshot.documentChanges.forEach((docChange) {
print(docChange.type.toString()+(docChange.document.metadata.isFromCache ? "doc from CACHE " : "doc from SERVER "));
});
}, onError: (error) {
print(error);
});
我最初得到的输出是:
颤振:我们得到了一个新的 QuerySnapshot
颤振: 5nAr5pYgwXJ0n3pWZkLw: from SERVER
颤振:moysGY7Ea7TCf28fcEVC:来自服务器
颤振:PuNnPaiLMIE7704R9NuL:来自服务器
flutter: 5nAr5pYgwXJ0n3pWZkLw: DocumentChangeType.adddoc from SERVER
颤振: moysGY7Ea7TCf28fcEVC: 来自服务器的 DocumentChangeType.adddoc
颤振:PuNnPaiLMIE7704R9NuL:来自服务器的DocumentChangeType.adddoc
然后,当我在服务器上进行更改时,它会打印:
颤振:我们得到了一个新的 QuerySnapshot
颤振: 5nAr5pYgwXJ0n3pWZkLw: from SERVER
颤振:moysGY7Ea7TCf28fcEVC:来自服务器
颤振:PuNnPaiLMIE7704R9NuL:来自服务器
flutter: 5nAr5pYgwXJ0n3pWZkLw: DocumentChangeType.modifieddoc from SERVER
因此,使用isFromCache
属性并不意味着确定文档是否是服务器上的收费读取,而是确定文档是否保证与服务器保持最新。
若要了解哪些文档已更改,可以循环访问documentChanged
集合,如上面的代码所示。
至于读取次数超过预期,造成这种情况的更常见原因之一是在 Firebase 控制台中保持 Firestore 面板打开。控制台执行的读取将计入您的项目。有关此内容的更多信息,请参阅:
- 谷歌云修复控制台读取所有文件和费用
- Firestore 集合侦听器大量读取
- Firestore - 意外读取