Firestore Data Bundles

A new implementation for cached Firestore documents

Firestore just got better

The Firebase Firestore recently got enhanced and now implements a new feature called “Firestore Data Bundles”. The core concept of it is that Firestore queries can now be packaged in binary format and served via your CDN or other hosting solution. Effectively this means that a certain group of your data might be well suited to not get fetched directly from the Firestore backend, but rather a CDN and thus can save you some costs.

But why? And more important, how?!

“Firestore Data Bundles” are actually really simple designed:

  • you first create a “data bundle”-reference in a server environment via the Admin SDK
  • then, this bundle gets loaded with standard Firestore queries
  • what you then have is a buffer of this data that can be stored as a file, for instance, or in your CDN
  • switching to your client side, all that’s now left using the new Firestore API to actually load the bundle from your CDN
// On your server ....

/**
 * Generate a buffered bundle for user tempaltes.
 */
async function getUserTemplatesBundle(){
  // Create a bundle with ID 'user-templates'.
  const bundle = firestore.bundle("user-templates");
  
  // A plain Firestore-query.
  const snap = await firestore.collection('user-templates').get();

  return bundle
          .add('user-templates-query', snap)
          .build();
}

// ... then store the buffer, e.g. in your CDN ...
// On your client

import firebase from "firebase/app";
import "firebase/firestore";
import "firebase/firestore/bundle";

// ... init 'firestore' ...

async function loadFirestoreBundle() {
  // Just a simplified call to our demo CDN
  // to fetch the bundle in binary form.
  const rawBundle = await fetchBundleFromCDN();
  // Now tell Firestore to load the bundle
  await firestore.loadBundle(rawBundle);

  // Now get a reference to the bundled query, in
  // our case it's only one query that got bundled.
  const query = await db.namedQuery('user-templates-query');
  
  // Use 'cache' as source so that the data gets
  // cached locally - no Firestore queries will
  // be executed.
  const snap = await query.get({ source: 'cache' });

  // Finally, you can handle the snap like every other
  // Firestore snap in your app.
}

The benefit of such a data bundle becomes clearer when looking at an example. Imagine you frequently use a default set of values for a new document in your Firestore, for instance when creating a new user. Instead of fetching from the database directly, you can now use “Firestore Data Bundles” to load these values as a cached document from your CDN, avoiding any costs that are associated with a Firestore-query.

This new feature is therefore best suited for documents that conform to the following requirements: the data doesn’t change often, the number of documents isn’t very large and many fetches for this data set will frequently happen.

Another real world example

As maybe an ideal use case, you can also take this progressive web app as an example. All translated texts are stored in a Firestore instance, as well as the URL-references to all audio files. Because this data doesn’t change much, if at all, it’s very well suited to be cached in either Firebase Storage or my CDN. This can potentially reduce my Firestore costs significantly.

“Firestore Data Bundles” are a very nice addition to Firebase. They might not cover your use cases for now, but could become very helpful when your service starts to grow.

Suggestions

Related

Addendum

Languages