Firebase 总是从互联网读取

Mah*_*poo 1 firebase flutter google-cloud-firestore

据我所知,Flutter 上的 Firebase 会首先自动从缓存中读取,但我注意到在开发过程中,一个应用程序只是玩弄几乎 1 个包含 10 或 15 个文档的流,我的读取次数超过了 4000 次!通过这种方式,如果 10 个用户使用了我的应用程序,我将支付我所有的费用,因此我重新检查了每个查询、快照并将此代码放入

print(itemDoc.metadata.isFromCache ? "itemDoc NOT FROM NETWORK" : "itemDoc FROM NETWORK");
Run Code Online (Sandbox Code Playgroud)

编辑写代码和更多解释

当我更新、添加、删除文档控制台打印所有存储的文档时,我注意到这个问题出现在 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");
             }
           )
          }
}
Run Code Online (Sandbox Code Playgroud)

Provider我在其中调用 main 函数的这两种方法Home.dart initState

 @override
  void initState() {
    Provider.of<ListsProvider>(context, listen: false)
        .userListsStream(uid);
  }
Run Code Online (Sandbox Code Playgroud)

Fra*_*len 6

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);
});
Run Code Online (Sandbox Code Playgroud)

我最初得到的输出是:

颤振:我们得到了一个新的 QuerySnapshot

颤振:5nAr5pYgwXJ0n3pWZkLw:来自服务器

颤振:moysGY7Ea7TCf28fcEVC:来自服务器

颤振:PuNnPaiLMIE7704R9NuL:来自服务器

颤振:5nAr5pYgwXJ0n3pWZkLw:来自服务器的 DocumentChangeType. addeddoc

颤振:moysGY7Ea7TCf28fcEVC:来自服务器的 DocumentChangeType. addeddoc

颤振:PuNnPaiLMIE7704R9NuL:来自服务器的 DocumentChangeType. addeddoc

然后当我在服务器上进行更改时,它会打印:

颤振:我们得到了一个新的 QuerySnapshot

颤振:5nAr5pYgwXJ0n3pWZkLw:来自服务器

颤振:moysGY7Ea7TCf28fcEVC:来自服务器

颤振:PuNnPaiLMIE7704R9NuL:来自服务器

颤振:5nAr5pYgwXJ0n3pWZkLw:来自服务器的 DocumentChangeType.modifieddoc

因此,使用该isFromCache属性并不意味着确定文档在服务器上是否是收费读取,而是要保证文档在服务器上是最新的。

要了解哪些文档发生了变化,您可以遍历documentChanged集合,如上面的代码所示。


至于读取次数超出您的预期,更常见的原因之一是在 Firebase 控制台中保持 Firestore 面板处于打开状态。控制台执行的读取计入您的项目。有关这方面的更多信息,请参阅: