Does Firestore cache query results?

Viewed 2459

Imagine I'll run a query on a specific collection that has 100 document.

I'll show 20 results per page, using query cursors.

If my user starts at page 1, and press the Next button until he sees page 5, he'll have read all 100 documents.

QUESTION

If he presses the Previous button going back from page 5 until page 1 again, will I be charged for 180 reads or Firestore has some sort of caching period where it would return the same results without any new reads?

180 = Pages 1 to 4 twice, and Page 5 a single time.

Note: I would fire a get() method on each page with the respective startAfter().

I'm asking that because from the pricing operations page, there's this info about listening query results:

Listening to query results

Cloud Firestore allows you to listen to the results of a query and get realtime updates when the query results change.

When you listen to the results of a query, you are charged for a read each time a document in the result set is added or updated. You are also charged for a read when a document is removed from the result set because the document has changed. (In contrast, when a document is deleted, you are not charged for a read.)

Also, if the listener is disconnected for more than 30 minutes (for example, if the user goes offline), you will be charged for reads as if you had issued a brand-new query.

Note: I know in this case I'm not setting up a listener, but I want to know if is there any analog behavior in my case.

1 Answers

Since you aren't setting up a listener, each call to get() will fetch the latest from the server and you will be charged for those reads. There are two ways to avoid being charged for fresh reads each time:

  1. Use an query.onSnapshot(...) listener, which will continuously update as the data changes.
  2. Use query.get({source: "cache"}) to fetch from the local cache. See GetOptions for details.

For (2) if there's no data in cache the get() will return a snapshot with no documents, so you'd either need to keep track of which pages you'd already fetched or do some kind of fallback:

let snap = await q.get({source: "cache"});
if (snap.empty) {
  // cache didn't have anything, so try a fetch from server instead
  snap = await q.get();
}
Related