Firestore - Using cache until online content updates

Diego Garcia picture Diego Garcia · Oct 22, 2017 · Viewed 13.6k times · Source

I am starting with Firestore. I've read docs and tutorials about the offline data persistence but I have not really clear if Firestore downloads data again even if the content hasn't been modified. For example, if I have a query where the results will be updated once a week and I don't need that the app download the content again until the changes were made, what is the best way in terms of efficiency to write the code? Thanks!

Answer

Sam Stern picture Sam Stern · Nov 7, 2017

You want to use the "snapshot listener" API to listen to your query: https://firebase.google.com/docs/firestore/query-data/listen#listen_to_multiple_documents_in_a_collection

Here's some JavaScript as an example:

db.collection("cities").where("state", "==", "CA")
    .onSnapshot(function(querySnapshot) {
        var cities = [];
        querySnapshot.forEach(function(doc) {
            cities.push(doc.data().name);
        });
        console.log("Current cities in CA: ", cities.join(", "));
    });

The first time you attach this listener Firestore will access the network to download all of the results to your query and provide you with a query snapshot, as you'd expect.

If you attach the same listener a second time and you're using offline persistence, the listener will be fired immediately with the results from the cache. Here's how you can detect if your result is from cache or local:

db.collection("cities").where("state", "==", "CA")
  .onSnapshot({ includeQueryMetadataChanges: true }, function(snapshot) {
      snapshot.docChanges.forEach(function(change) {
          if (change.type === "added") {
              console.log("New city: ", change.doc.data());
          }

          var source = snapshot.metadata.fromCache ? "local cache" : "server";
          console.log("Data came from " + source);
      });
  });

After you get the cached result, Firestore will check with the server to see if there are any changes to your query result. If yes you will get another snapshot with the changes.

If you want to be notified of changes that only involve metadata (for example if no documents change but snapshot.metadata.fromCache changes) you can use QueryListenOptions when issuing your query: https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/QueryListenOptions