Firestore query reads all the documents again (from database) when only one is modified even with persistence enabled

后端 未结 1 846
北荒
北荒 2020-12-07 01:55

Expected Behavior: I assumed that when some field of a document is modified, query will only return that document and so it would be considered only 1 read.

相关标签:
1条回答
  • 2020-12-07 02:20

    I noticed this behavior and did some research: actually all is well!

    When you are listening to a collection of N documents, you perform N reads for the initial state, then 1 read when a documents changes, as expected. This is described nicely in this youtube video, and in the documentation for the billing aspect.

    The trap is the fromCache metadata. When you receive an update for a document change, all the other unchanged documents have fromCache: false, but they actually come from the cache, as described by a Firebase dev in this SO answer!

    The fromCache metadata is true only in the scope of offline persistence, when the initial N reads were done from the local cache. When a document has received data from the server, it sets fromCache: false, and never goes back to fromCache: true. The naming is disturbing, but it seems to be working as expected.

    And the code for testing:

    <html>
        <body>
            <script src="/__/firebase/7.22.1/firebase-app.js"></script>
            <script src="/__/firebase/7.23.0/firebase-firestore.js"></script>
            <script src="/__/firebase/init.js"></script>
            <script>
                firebase.firestore().enablePersistence().then(() => {
                        const collectionRef = firebase.firestore().collection("/fruits");
                        collectionRef.onSnapshot({includeMetadataChanges: true}, snapshot => {
                        console.log("=================== snapshot received ===================");
                        snapshot.forEach(doc => {
                            console.log(`doc ${doc.id}, metadata:`, doc.metadata);
                        });
                    });
                });
            </script>
        </body>
    </html>
    

    I modify a document using Firebase console, and in my browser's console, when the long polling request terminates, it shows that a single document was transferred:

    15
    [[14,["noop"]]]370
    [[15,[{
      "documentChange": {
        "document": {
          "name": "projects/xxx/databases/(default)/documents/fruits/apricot",
          "fields": {
            "color": {
              "stringValue": "red"
            }
          },
          "createTime": "2020-10-13T08:14:19.649748Z",
          "updateTime": "2020-10-13T14:16:09.991161Z"
        },
        "targetIds": [
          2
        ]
      }
    }
    ]]]122
    [[16,[{
      "targetChange": {
        "resumeToken": "CgkI+bft8+Cx7AI=",
        "readTime": "2020-10-13T14:16:09.991161Z"
      }
    }
    ]]]15
    [[17,["noop"]]]
    
    0 讨论(0)
提交回复
热议问题