【问题标题】:Firebase always reads from internetFirebase 总是从互联网上读取数据
【发布时间】:2020-04-24 22:15:35
【问题描述】:

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

print(itemDoc.metadata.isFromCache ? "itemDoc NOT FROM NETWORK" : "itemDoc FROM NETWORK");

编辑写代码和更多解释

当我更新、添加、删除文档控制台打印所有存储的文档时,我注意到这个问题出现在 IOS 中。

我有获取所有用户列表的 Main Stream 然后我为它创建流的每个列表来监听列表的项目

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中的那两个方法,我在Home.dart中调用main函数initState

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

【问题讨论】:

  • 请编辑您的问题以包含产生输出的最少、完整的代码。目前还不清楚你是如何阅读的,这让人很难理解。
  • @FrankvanPuffelen 我添加了一些额外的数据,如果您需要任何其他数据,请告诉我
  • 糟糕,没关系...我已经颠倒了我的印刷声明。你是对的,对我来说,它也一直在打印FROM SERVER。这显然是错误的。让我看看我是否能找到一些关于为什么会发生这种情况的信息。
  • 我刚刚了解到isFromCache 的工作方式与我的想法完全不同。我将再进行一些测试,然后写出答案。

标签: firebase flutter google-cloud-firestore


【解决方案1】:

isFromCache 标志表明文档是否保证与服务器保持同步,或者它可能是缓存中的陈旧结果。如果是false,并不一定意味着该文档是从服务器读取的,但可以保证该文档与服务器是最新的。

为了说明这意味着什么,我可以用这个 sn-p

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);
});

我最初得到的输出是:

flutter:我们得到了一个新的 QuerySnapshot

颤动:5nAr5pYgwXJ0n3pWZkLw:来自服务器

颤振:moysGY7Ea7TCf28fcEVC:来自服务器

颤振:PuNnPaiLMIE7704R9NuL:来自服务器

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

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

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

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

flutter:我们得到了一个新的 QuerySnapshot

颤动:5nAr5pYgwXJ0n3pWZkLw:来自服务器

颤振:moysGY7Ea7TCf28fcEVC:来自服务器

颤振:PuNnPaiLMIE7704R9NuL:来自服务器

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

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

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


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

【讨论】:

    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    相关资源
    最近更新 更多