Today, Google launched a new add-on to one of it’s flagship product Firebase called Firestore, which is a new NoSQL database that can be used with any existing or new Firebase application. But now the question rises that while Firebase is already a Realtime Database why do we need a new add-on for NoSQL database? And the reason for it is that earlier for building a complex application like CRM or a social networking website using Firebase real-time database it turns out to be such a pain that you can’t build complex queries. Right now with Firestore its much easier and powerful and you don’t have to do a lot of denormalizing anymore.

I’ll explain the complex queries, searching and other advanced features in the upcoming articles, while this article will be focused on understanding the basics.

There are two important things you need to know before jumping into Firestore, they are the Collections and Documents.

1. Collections

Collections are the containers for documents and it will always hold documents and never can hold data.

2. Documents

Documents hold the actual data and are contained in collections. It supports various types of data which are listed here.

The Setup#

In order to use Firestore you need to import the library.

Via CND

< script src = "https://www.gstatic.com/firebasejs/4.5.0/firebase-app.js" ></ script > < script src = "https://www.gstatic.com/firebasejs/4.5.0/firebase-firestore.js" ></ script >

Via NPM

require("firebase/firestore");

Once imported initialize the application with the configuration data from Firebase console

Initialize

var config = { apiKey : "YOUR__API__KEY" , authDomain : "YOUR__AUTH__DOMAIN" , databaseURL : "YOUR__DATABASE_URL" , projectId : "YOUR__PROJECT__ID" , }; firebase . initializeApp ( config );

Let’s create a Simple TODO application As usual for getting started let’s start with the traditional example of a todo application. Here we need the following elements,

A Textbox

A Button for submitting

A list for listing all todos

Let’s go ahead and create them.

Todo Form

< div class = "todoCreate" > < input type = "text" id = "todoInput" placeholder = "Todo Title" > < button id = "submitButton" >Create</ button > </ div >

Todo List Element

< ul id = "listTodos" ></ ul >

Now let’s create the corresponding DOM objects and listeners for these elements

Defining the DOM elements

var todoInput = document. querySelector ( "#todoInput" ); var submitButton = document. querySelector ( "#submitButton" ); var listTodos = document. querySelector ( "#listTodos" );

Attaching a listener function

todoInput . addEventListener ( 'keyup' , handleSubmit ); submitButton . addEventListener ( 'click' , handleSubmit );

Here the handleSubmit will be the function that will listener when the button is clicked or textbox values are changed.

Setup Firestore Ref

To access a collection in Firestore is almost similar to Firebase real-time database, you need to create a ref object and with it you can access the data.

const todoRef = firebase.firestore().collection("todos");

Listener Function

function handleSubmit ( e ) { if ( e . keyCode !== 13 && e . type != "click" ) { return ; } const todo = todoInput . value ; submitButton . innerHTML = "Creating..." ; if ( todo === "" ) { return ; } todoRef . add ({ title : todo , checked : false , createdAt : ( new Date()). getTime () }). then ( function ( docRef ) { todoInput . value = "" ; submitButton . innerHTML = "Create" ; }). catch ( function ( error ) { console . log ( error ); }) }

In the above code once the validations complete we’re creating the todo in Firestore with the function called .add()

You need pass the todo object for the add function and it returns a promise so you can use then and catch to find if success or not.

Listing the todos

To fetch all the todos we can use the same ref variable and use get() method to get all the documents inside the todo collection. But inorder to listen to updates we need to use onSnapshot method which is similar to on() method in Firebase real-time database.

// Listener for rendering todos todoRef . orderBy ( "createdAt" , 'desc' ). onSnapshot ( function ( docSnapShot ) { listTodos . innerHTML = "" ; docSnapShot . forEach ( function ( doc ) { todo = doc . data (); todo . id = doc . id ; var checkBox = document. createElement ( "INPUT" ); checkBox . setAttribute ( "type" , "checkbox" ); checkBox . setAttribute ( "data-id" , todo . id ); checkBox . checked = todo . checked ; checkBox . addEventListener ( 'change' , handleCheckToggle ); var titleBlock = document. createElement ( "h3" ); titleBlock . innerHTML = todo . title ; var wrapper = document. createElement ( 'div' ); wrapper . appendChild ( checkBox ); wrapper . appendChild ( titleBlock ); listTodos . appendChild ( wrapper ); }) })

As you can see in the above code we’re listening to changes in the ref and when ever we get an update we’re clearing the list and relisting it. Also we’ve used a small ordering query to order by the created at time, which was not possible with realtime database, you can do a lot more things with it which I’ll be covering in the next articles.

Also here unlink Realtime DB we’re getting ID instead of key as the unique value. Once I get each todo I’m adding it to the list with a title and a checkbox, also attaching a listener for checkbox’s change event which is used to update the status.

Now in order to update the status of the todo we use the below function.

function handleCheckToggle ( e ) { var targetElement = e . target ; var checked = targetElement . checked ; var id = targetElement . dataset . id ; todoRef . doc ( id ). update ({ checked : checked , }) }

Now this gets you a complete example of a very simple todo. In my next article I’ll write about how to use cloud function triggers for Firestore, managing multiple collections, and more advanced queries.

I feel that Firebase is now a much more matured product than earlier.

Also do checkout our other articles on Firebase here: