In another article, we describe how to use the Firestore and Collection classes. They allow you to load, view, and edit data in your Firestore databases using the low-level REST APIs, which are light and fast, but do not provide the advanced features made available by the Firestore web client library, such as off-line caching and real time updates.

The Snapshot class extends the CollectionView class to provide access to Firebase collections and queries. It relies on the web client library to provide real time updates and other advanced features. To use the Snapshot class, you must load the web client library from NPM or CDN.

Creating a Snapshot

Once you have loaded the web client libraries, you may create and use the Snapshot class as follows:

 // initialize Firestore web client library
 const firebaseConfig = {
     apiKey: …
     authDomain: …,
 };
 firebase.initializeApp(firebaseConfig);

 // get a snapshot of the "restaurants" collection
 const db = firebase.firestore();
 let restaurants = db.collection('restaurants');
 let snapshot = new Snapshot(restaurants, {
     query: restaurants.where('type', 'in', ['Japanese', 'Italian' ])
 });

 // bind the snapshot to a FlexGrid
 new FlexGrid('#theGrid', {
     itemsSource: snapshot
 });

The code above starts by initializing the web client library. It then builds a Snapshot based on the content of the "restaurants" collection where the restaurant type is "Japanese" or "Italian."

The query property can be changed at any time, but it should always be based on the "restaurants" collection.

Finally, the code uses the Snapshot as a data source for a FlexGrid.

If anyone makes changes to the "restaurants" collection, the Snapshot will be notified, and the grid will be updated automatically.

Enable Authentication

The Snapshot class uses the web client libraries and relies on their authentication mechanism.

Most applications apply restrictions to read and write operations so only certain users can see or edit the data. The web client libraries integrate with the Firestore database security rules. You can create, review, and modify the rules at the Firebase console. For example:

In our example, the rules are set up so anyone can read the data, but only certain users can make changes. The users are defined using an "admins" collection within the database. The "admins" collection contains the e-mail of users who are authorized to write to the database.

The rule looks like this:

service cloud.firestore {
   match /databases/{database}/documents {
     match /{document=**} {
       allow read;
       allow write: if exists(/databases/$(database)/documents/admins/$(request.auth.token.email));
     }
   }
 }

You can use the OAuth2 class to authorize users as we did before when using the Firestore class. The only difference is when using the web client libraries, you do not use the accessToken property as before. Instead, you must create a credential object based on the idToken provided by the OAuth2 class and use that credential to sign with the Firebase client libraries.

 // update state when user changes
 auth.userChanged.addHandler(s => {
     let user = s.user;
     oAuthBtn.textContent = user ? 'Sign Out' : 'Sign In';

     // update Firestore access tokens
     //fs.accessToken = user ? s.accessToken : null;

     // Sign in with credential from the Google user.
     // https://firebase.google.com/docs/auth/web/google-signin
     if (user) {
         let credential = firebase.auth.GoogleAuthProvider.credential(s.idToken);
         firebase.auth().signInWithCredential(credential);
     } else {
         firebase.auth().signOut();
     }
 });

The log in/out experience is the same as before, but you do get some extra flexibility by being able to use and customize the Firestore security rules.

Once the user has been authenticated, he will be able to edit the data in the Snapshot (if his email is in the "admins" collection).

Realtime Updates

If you run this app and open two instances of the browser, you will be able to make changes in one instance and see them applied immediately to the other.

Realtime updates are not necessary for all types of all, but they can be crucial in some cases. And Firestore makes it easy to get them when you need them.

Try the Live Demos

Try Wijmo's JavaScript UI library

Download the latest version of Wijmo

Download Now!