Storing your notes in the Cloud Firestore with Vuejs.
Tags: vue, firestone
Published: 2020-01-23 20:32:06

---
title: Storing your notes in the Cloud Firestore with Vuejs.
published: true
date: 2020-01-23 19:58:45 UTC
tags: vue, firestone
canonical_url: https://labs.thisdot.co/storing-your-notes-in-the-cloud-firestore-with-vuejs
---

In my [recent article](https://dev.to/thisdotmedia/vue-the-mirage-from-this-angle-352p), we built a Notes Writer Vue.js app that demonstrated how Mirage.js (an in-memory client-side server library) simulates REST API responses for your client-side app.

Now, we will take the Notes Writer app to another level by introducing the Cloud Firestore. Firestore is a serverless database service, offered by Google Firebase. We'll use the Cloud Firestore as a backend database for this app to persist and manage the notes.

As you go through the article, it will be clear that only the code for the Vuex Store is affected by introducing Cloud Firestore to the app. Some functions become void, and the entire code becomes simpler.

This article assumes a basic knowledge of using the Firebase Firestore library API. If you need some additional clarification, I’ve made sure to include some hyperlinks to help you locate what you want, and learn it quickly.

The source code of this article can be cloned from this GitHub repo: [Notes Writer](https://github.com/bhaidar/notes-writer/tree/firebase-firestore-integration).

## Google Firebase
The Cloud Firestore is a member of the Google Firebase family. Google Firebase is a Mobile and Web development platform offering cloud-based services to quicken the development process. Some of the products include:

### Cloud Firestore
A serverless real-time NoSQL [database engine](https://firebase.google.com/docs/firestore).

### Authentication
An authentication engine that is capable of authenticating your users via social networks like Google, Twitter, and Facebook, to mention a few. (https://firebase.google.com/docs/auth). 

### Cloud Functions
A platform and engine to build, deploy and run [Cloud Functions](https://firebase.google.com/docs/functions) with Google Firebase.

### Hosting
A platform to host your application, whether the app is a static or dynamic app. This [platform](https://firebase.google.com/docs/hosting) offers a rich toolbox to test your apps locally before deploying them live.

### Cloud Storage
This service offers developers a [bucket to store](https://firebase.google.com/docs/storage) and serve user-generated content, such as photos, videos, or any other type of files.

### ML Kit
A new member in the Google Firebase family. This service allows developers to introduce [Machine Learning services](https://firebase.google.com/docs/ml-kit) to help solve real-life complex problems.

### Documentation
The Google Firebase team has done a great job offering detailed, and quality documentation, covering all aspects of Firebase. Instead of repeating the same material here, I'll provide the relevant links that will bring you up to speed on Cloud Firestore and Firebase in general.

[How to add and setup Firebase in your app](https://firebase.google.com/docs/web/setup)
[Cloud Firestore docs](https://firebase.google.com/docs/firestore)
[Firebase API reference](https://firebase.google.com/docs/reference)
[Firebase Libraries](https://firebase.google.com/docs/libraries)
[Firebase App samples](https://firebase.google.com/docs/samples)

Moving on, we will be using the Cloud Firestore as both a database engine, and a real-time database to listen to new Notes that are being added to the app.

## Demo
Let’s start by creating a new Git branch by running this command:

```bash
git checkout -b firebase-firestore-integration
```

The command creates and checks out a new Git branch. 

### Install Firebase
There are several approaches to incorporating Firebase in your app. I will install the Firebase NPM package. Let’s go ahead and install this package by running the command:

```bash
npm install --save firebase
```

This installs all that's required to start developing with Firebase.

### Create a new Firebase project
Before you start using any Firebase service, you must create a new Firebase project. Visit the Firebase Website by pasting the following URL in your browser: [Firebase Website](https://firebase.google.com/?authuser=1).

If you are not signed in, you will be redirected to the Sign in/up page. Right after signing in, you are transferred to the Firebase home page. 

Click the `Go to console` hyperlink to get started.

Click the `Add project` tile to start creating your first Firebase project.

![Screenshot 2019-12-13 at 10.18.38 PM](//images.ctfassets.net/zojzzdop0fzx/7vrtbl1ApfZZYg6bq8rZUg/53a720f4e6432b9a6ec9e0a6084bf4ba/Screenshot_2019-12-13_at_10.18.38_PM.png)

Fill in a name for the new project and accept the Firebase terms and conditions. Once done, click `Continue`.

![Screenshot 2019-12-13 at 10.20.39 PM](//images.ctfassets.net/zojzzdop0fzx/33cXjIPnFBCQwUcWcK2q3D/8e08388d90a5a4596cfe8d508748bb65/Screenshot_2019-12-13_at_10.20.39_PM.png)

In the next step, I choose to disable the Google Analytics. You are free to enable it.

On the Google Analytics page, locate the `Create project` button to establish the project. The process usually takes a few seconds to finish setting up everything.

A new screen shows up with information about the creation process. Once the new project is ready, click the `Continue` button to go the project page.

![Screenshot 2019-12-13 at 10.26.02 PM](//images.ctfassets.net/zojzzdop0fzx/7lcBCS9m91xyWUkD4ynVzD/a353fc91a2907a538b98b718fdc4adb3/Screenshot_2019-12-13_at_10.26.02_PM.png)

Expand the `Develop` menu. You will be spending most of your time using the features under this menu, and specifically, the `Database` menu options in this article.

### Create a new Firebase Web app
Now that the Firebase project is created, it’s time to create your first Firebase Web app. A Firebase project consists of multiple apps. For instance, an iOS Mobile backend app, Android Mobile backend app, Web backend app, and other types of apps.

For this project, we will be creating a Web backend app. Locate and click the `gear icon` near the `Project Overview` menu item. Then, click the `Project Setting` hyperlink to go to the project settings.

![Screenshot 2019-12-13 at 10.35.43 PM](//images.ctfassets.net/zojzzdop0fzx/FSGTxWErgmKn8mPf3bdyV/242e99bc51361422746c875f46c8fda6/Screenshot_2019-12-13_at_10.35.43_PM.png)

On the Project Settings page, you can check the project settings, Web API key, Project ID, and other project-related information.

Under the `General` tab, scroll down to reach the `Your apps` section. Click the `Web App` icon as shown below.

![Screenshot 2019-12-13 at 10.38.29 PM](//images.ctfassets.net/zojzzdop0fzx/RzwxgQ3K5U0bGwvwgZQOm/537a1f9d2a8888c2ca16e408b0bb561a/Screenshot_2019-12-13_at_10.38.29_PM.png)

A new screen pops up to collect some information about your new app before it gets registered under Firebase.

![Screenshot 2019-12-13 at 10.40.58 PM](//images.ctfassets.net/zojzzdop0fzx/4xa7EXt1qK4Ar1vcgDRyPM/6b444c07bacc2687c97c3fdd3bbdc693/Screenshot_2019-12-13_at_10.40.58_PM.png)

Provide a name for the new app. Also, select the option to set up Firebase Hosting for this app. We might be using this option later, but it’s better to select it now.

Locate and click the `Register app` button to get started registering the new app.

You may skip the scripts section, and click the `Next` button right away.

![Screenshot 2019-12-13 at 10.43.25 PM](//images.ctfassets.net/zojzzdop0fzx/4F1vk8226RtcZ72Wt1TCR0/c2ffeaee4bdbb1a585331dfaada45b86/Screenshot_2019-12-13_at_10.43.25_PM.png)

You are then asked to install the Firebase CLI that we might use later on to host the Notes Writer app on Firebase.

Copy the command and run it locally on your computer to install it globally.

Locate the `Next` button on the screen to move forward. You are given detailed information on how to deploy your app to Firebase. We will skip these steps for now, and come back to it later.

![Screenshot 2019-12-13 at 10.48.09 PM (1)](//images.ctfassets.net/zojzzdop0fzx/3tMt0NV1WnI9yMR9cDScgO/6f07af17abd6bdecf3bccb16b16121ad/Screenshot_2019-12-13_at_10.48.09_PM__1_.png)

Click the `Continue to console` button to start managing your new app.

You are redirected back to the `Project Settings` page. Scroll down until you find your new Web app section. Locate the section `Firebase SDK snippet`, and make sure the `config` option is selected:

![Screenshot 2019-12-13 at 10.56.51 PM](//images.ctfassets.net/zojzzdop0fzx/vHzl96vXHz7LHjrjkuFyS/bf22c894feb77f415335f9b1deb1996c/Screenshot_2019-12-13_at_10.56.51_PM.png)

The `firebaseConfig` object has all the settings needed to allow your client-side app to connect to Firebase.

Copy this object, go back to the code editor, and create a new file named `firebaseConfig.js` at the root folder of your app. Then, paste this object inside the file. We will revisit this file shortly.

### Create the database
Now that the app is ready, we are free to create an instance of the Cloud Firestore database.

Locate and click the `Database` menu item under the `Develop` menu.

![Screenshot 2019-12-13 at 11.24.44 PM](//images.ctfassets.net/zojzzdop0fzx/2wW9Nfe0c7PFQCLzrHleOF/6ed728dce874cd0c93a45059dc3a621f/Screenshot_2019-12-13_at_11.24.44_PM.png)

Click the `Create database` button to create a new database.

![Screenshot 2019-12-13 at 11.26.01 PM](//images.ctfassets.net/zojzzdop0fzx/6T8KtuYUd9fiUsb2hAwf7i/bf1a39d206aedde0cb3f6bc13ad38d6b/Screenshot_2019-12-13_at_11.26.01_PM.png)

On the `Create database` Modal window, make sure you select the `Start in test mode` option. This removes any restrictions on reading, adding, deleting, and editing data inside the database. Once you are ready for production, you may revisit the database settings, enable the `production mode`, and define rules for user access permissions.

Click the `Next` button to select a geographical location for this new database.

![Screenshot 2019-12-13 at 11.28.38 PM](//images.ctfassets.net/zojzzdop0fzx/1KBOMjsoa0K3GjeBUXKjQt/edafa4a1d3e0a64f62bf1eab4761487e/Screenshot_2019-12-13_at_11.28.38_PM.png)

Make sure to select the nearest location to you. Finally, click the `Done` button. Firebase takes a few seconds to provision the new database. Then, you are redirected to the new Database page to start managing the data.

Historically, Firebase supported a realtime database engine. The Cloud Firestore is a successor to that engine, and is the recommended option for almost all scenarios. You can read more about the [Firebase Realtime Database](https://firebase.google.com/docs/database).

![Screenshot 2019-12-13 at 11.39.05 PM](//images.ctfassets.net/zojzzdop0fzx/bb2LwhBm9qb5Qs9dfffZn/e342cd8236723261be16bf7dbd8ea2ed/Screenshot_2019-12-13_at_11.39.05_PM.png)

Just as a Relational Database engine structures and defines data in terms of Tables, Rows, and Columns, the Cloud Firestore is a NoSQL database engine structures that defines data in terms of Collections, Documents, and the relationships between Documents and Collections.

Let’s create the `Notes` collection by clicking the `Start collection` hyperlink.

![Screenshot 2019-12-13 at 11.46.00 PM](//images.ctfassets.net/zojzzdop0fzx/1B4BnnAZMtAQGU3RWok1iH/927908b976c96b68ae397e2c06ce3551/Screenshot_2019-12-13_at_11.46.00_PM.png)

Give your new collection the name of `notes`. Then click the `Next` button.

![Screenshot 2019-12-13 at 11.49.36 PM](//images.ctfassets.net/zojzzdop0fzx/rii7RNW4IYXRzdAgICKnU/124d63093203e1d3fad4382f248995d6/Screenshot_2019-12-13_at_11.49.36_PM.png)

Create your first Document by adding the fields that you want to appear on a single Note record. Notice that the `Document ID` can be auto generated by Firestore, or you can give it a unique value yourself. I choose to keep it managed by Firestore.

Starting by adding the `body` and `title` fields. Give them both the `string` data type, and fill in a value.

You may add more fields. In this case, I will add the `createdOn` and `updatedOn` fields of type `timestamp`.

![Screenshot 2019-12-13 at 11.51.20 PM](//images.ctfassets.net/zojzzdop0fzx/1Exa7aFZmtntUujVFf2uTr/c58e6a454830daf959cf905e76a68ee4/Screenshot_2019-12-13_at_11.51.20_PM.png)

Once done filling the data, click the `Save` button.

![Screenshot 2019-12-13 at 11.52.05 PM](//images.ctfassets.net/zojzzdop0fzx/7vKUvWLdbW8iGiir1o5QXS/bd227f2615c6569263169eb86c48e759/Screenshot_2019-12-13_at_11.52.05_PM.png)

You can now see our new `notes` collection together with the first document added, and the details of that document.

You may add more Notes documents by clicking the `Add document` hyperlink. You will follow the same process to add new Documents.

Now that the database is up and running, let's go back to the Notes Writer app, and start refactoring the code to make use of the Firestore database to load and manage Note in the app.

### Connect app to Firebase
It’s time now to start interacting with the Firebase Firestore from within our Notes Writer app.

Revisit the `firebaseConfig.js` file at the root of the application folder, and paste the following:

```javascript
import firebase from 'firebase/app'
import 'firebase/firestore'

// firebase init
const firebaseConfig = {
    ....
...
};

firebase.initializeApp(firebaseConfig)

// firebase utils
const db = firebase.firestore()

// firebase collectionsa
const notesCollection = db.collection('notes')

export {
    firebase,
    db,
    notesCollection
}

```

Make sure to copy your own `firebaseConfig` object from the Firebase app settings.

Start by importing the `firebase` object, and also the `firebase/firestore` library.

Given that you have copied and pasted a valid `firebaseConfig` object, initialize the communication with Firebase by calling the `firebase.initializeApp()` function, passing the `firebaseConfig` object as a parameter.

Store an instance of the Firestore client API inside a variable named `db`.

Also, retrieve a reference to the `notes` collection, and store it inside the variable named `notesCollection`.

Finally, export a few objects to be imported and used in other places in the app.

Open the `/store/index.js` file. Import the `firebaseConfig` file at the top of the store as follows:

```javascript
const fb = require('./../firebaseConfig.js')
```
We are going to use the realtime database feature to get notified when new Notes documents are created so that we load them inside the store. Add the following section outside the store object:

```javascript
fb.notesCollection.orderBy('createdOn', 'desc').onSnapshot(querySnapshot => {
  let notesArray = []

  querySnapshot.forEach(doc => {
    let note = doc.data()
    note.id = doc.id
    notesArray.push(note)
  })

  store.commit('loadNotes', notesArray)
})
```

The key here is to use the `onSnapshot()` function that is accessible on the `notesCollection` object.

Whenever a new document is added, updated or deleted, the `onSnapshot()` callback is called with all the information encapsulated inside the `querySnapshot` variable.

The code loops over all the Notes documents returned, populates an array of all notes, and then commits the array to the store by calling the mutation `loadNotes`.

Any time me or someone else creates, updates, or deletes a Note document, the `onSnapshot()` callback is executed, and therefore, our store is always up to date.

The `loadNotes` mutation is defined as follows:

```javascript
   loadNotes (state, notes) {
      state.notesList = notes
    },
```

I’ve amended the `states` object to include the following:

```javascript
 state: {
    notesList: [],
    note: {},
    performingDelete: false,
    performingAdd: false,
    performingUpdate: false
  },
```

The store now tracks a boolean flag to know whether there is an active request to either delete a Note, add a Note, or update a Note. These flags can be used to show/hide UI in the app, and give a visual feedback to the user of the app.

The `deleteNote` action is defined as follows:

```javascript
async deleteNote ({ commit, state }) {
      let id = (state.note && state.note.id)

      if (id) {
        try {
          commit('setPerformingDelete', true)
          await fb.notesCollection.doc(id).delete()
          commit('setPerformingDelete', !state.performingDelete)
        } catch (error) {
          console.error(error)
        }
      }

      commit('setNote', {})
    },
```

The action starts by retrieving the note’s details to delete. If there is a valid Note Id, it continues.
It starts by setting the `setPerformingDelete` state flag to `true`.
It issues a call on the Firebase client API to delete a document specifying the Note document ID.
It then toggles the value of the `setPerformingDelete’ state flag back to `false`, signaling the end of deleting a Note document request.
Finally, the action resets the current active Note to clear the display.

The entire code is wrapped inside a`try/catch` block.

Notice though we are not manually removing the Note document from the Store state. Instead, we just issue a request to delete the Note document. The new list of Notes Documents will be retrieved via the `onSnapshot()` realtime database feature. Less code for you to write now!


Let’s implement the `saveNote` action:

```javascript
async saveNote ({ commit, state }) {
      const { id, body, title } = state.note

      if (id) { // update
        commit('setPerformingUpdate', true)
        await fb.notesCollection.doc(id).update({
          body,
          title,
          updatedOn: fb.firebase.firestore.Timestamp.now()
        })
        commit('setPerformingUpdate', !state.performingUpdate)
      } else { // add
        commit('setPerformingAdd', true)
        await fb.notesCollection.add({
          body,
          title,
          createdOn: fb.firebase.firestore.Timestamp.now(),
          updatedOn: fb.firebase.firestore.Timestamp.now()
        })
        commit('setPerformingAdd', !state.performingAdd)
      }

      commit('setNote', {})
    }
```

The code distinguishes between updating an existing Note document or adding a new one. In both cases, we set the flag to whether the app is updating a record inside Firebase Firestore or adding a new one.

In case we are updating an existing Note document, the code calls the `update()` function on the Note document reference. The `updatedOn` field is set to a value of `fb.firebase.firestore.Timestamp.now()`.

From the Firebase documentation:

> A Timestamp represents a point in time independent of any time zone or calendar, represented as seconds, and fractions of seconds at nanosecond resolution in UTC Epoch time.

You can read more information on [firebase.firestore.Timestamp](https://firebase.google.com/docs/reference/node/firebase.firestore.Timestamp)
In case we are adding a new Note document, the code calls the `add()` function on the `noteColletion` object passing as input a Note object including values for `createdOn` and `updatedOn`.

Finally, the action resets the current active Note to clear the display.

You can review the entire store file on Github:
https://github.com/bhaidar/notes-writer/blob/firebase-firestore-integration/src/store/index.js
One minor change I introduced to the store is removing the `getters`, and directly accessing state data. If a getter is not doing any logic, there is no need to keep this getter. Simply access the state data directly. Thank you, [Simone](https://dev.to/zelig880), for bringing this to my attention!

## Conclusion
This article demonstrates how to integrate Firebase Firestore into your front-end app by giving a step-by-step guide of what's required to create a Firebase app, add a Firestore database, and connect the app to Firebase.

Very soon, I will be using the Firebase Authentication to allow users to login to the Notes Writer app, and manage their own set of Notes, independent of other users using the same app.

Stay tuned!