Build Firestore Database CRUD Web App using Vue.js and Firebase

Build Firestore Database CRUD Web App using Vue.js and Firebase
A comprehensive step by step tutorial on build Firestore Database CRUD Web Application using Vue.js 2 and Firebase.
Originally published at https://www.djamware.com

In this tutorial, we are using standard Firebase module for Javascript. Starting from the Firebase connection to Firestore Database CRUD (Create, Read, Update, Delete) operation.

Table of Contents:

  • Setup Firebase Firestore Database
  • Install Vue-CLI 3 and Create Vue.js App
  • Install and Configure the Firebase Module
  • Add Vue.js Router
  • List of Boards using Bootstrap-Vue
  • Show Details and Delete Board using Bootstrap-Vue
  • Add Board using Bootstrap-Vue
  • Edit Board using Bootstrap-Vue
  • Run and Test Vue.js Firebase Firestore Web Application

The following tools, framework, and module are required for this tutorial:

  • Node.js (Recommended version)
  • Vue.js
  • Firebase
  • Terminal (Mac/Linux) or Node Command Line (Windows)
  • IDE or Text Editor

We assume that you have already installed Node.js. Make sure Node.js command line is working (on Windows) or runnable in Linux/OS X terminal.

Setup Firebase Firestore Database

Setup Google Firebase is very simple. Open your browser then go to Google Firebase Console and log in using your Google account.

Click the `Add Project` button, name it as you like and checks all checkboxes. Finally, click `Create Project` button then wait a few seconds and click the `Continue` button. You will be redirected to this page.

Go to Develop menu on the left menu then click `Create Database` on Cloud Firestore page.

Choose `Start in test mode` then click `Enabled` button.

Click `Add Collection` button to add the new collection for this tutorial. Fill collection ID (ours: 'boards') then click next. Add the required fields then click finish the wizard.

Now, the Firebase Firestore Database is ready to access. Make sure that your iOS and Android app match with the configuration files (json/plist). You can get the configuration parameters in the Authentication side menu then you will see the Web Setup button on the top right of the screen.

Install Vue-CLI 3 and Create Vue.js App

Vue CLI is a full system for rapid Vue.js development with the current latest version is 3. To install Vue-CLI 3 type this command from the Terminal or Node command line.

sudo npm install -g @vue/cli

or

yarn global add @vue/cli

Next, check the version to make sure that you have the 3.x version of Vue-CLI.

vue --version

Next, create a new Vue.js project by type this command.

vue create vue-firestore

For now, use the default for every question that shows up in the Terminal. Next, go to the newly created folder.

cd ./vue-firestore

To make sure that created Vue.js project working, type this command to run the Vue.js application.

npm run serve

or

yarn serve

You will see this page when open `http://localhost:8080/` in the browser.


Install and Configure the Firebase Module

We use Firebase module to access the Firebase Firestore Database. For that, type this command to install the module.

npm install --save firebase

Next, create a new file `Firebase.js` in the root of the project folder for Firebase configuration.

touch src/Firebase.js

Open and edit src/Firebase.js then replace all codes with this.

 import * as firebase from 'firebase';

import firestore from 'firebase/firestore'

 

const settings = {timestampsInSnapshots: true};

 

const config = {

  apiKey: "YOUR_API_KEY",

  authDomain: "YOUR_AUTH_DOMAIN",

  databaseURL: "YOUR_DATABASE_URL",

  projectId: "YOUR_PROJECT_ID",

  storageBucket: "YOUR_STORAGE_BUCKET"

};

firebase.initializeApp(config);

 

firebase.firestore().settings(settings);

 

export default firebase;

You can find or get those configuration parameters by click on Web Setup button in the page authentication of Firebase Console.

Add Vue.js Router

By default `vue-router` is not installed. For that, type this command to install that module.

npm install --save vue-router

To register or create routes for the whole application navigation, create a router folder and `index.js` file.

mkdir src/router 
touch src/router/index.js

Open and edit src/router/index.js then add these imports of VueRouter and the required created components.

import VueRouter from 'vue-router'
import BoardList from '@/components/BoardList'
import ShowBoard from '@/components/ShowBoard'
import AddBoard from '@/components/AddBoard'
import EditBoard from '@/components/EditBoard'

Add the router to each component or page.

export default new VueRouter({
  routes: [
    {
      path: '/',
      name: 'BoardList',
      component: BoardList
    },
    {
      path: '/show-board/:id',
      name: 'ShowBoard',
      component: ShowBoard
    },
    {
      path: '/add-board',
      name: 'AddBoard',
      component: AddBoard
    },
    {
      path: '/edit-board/:id',
      name: 'EditBoard',
      component: EditBoard
    }
  ]
})

Add Vue files for above-registered components or pages.

touch src/components/BoardList.vue
touch src/components/ShowBoard.vue
touch src/components/AddBoard.vue
touch src/components/EditBoard.vue

Finally, add or register this router file to `src/main.js` by adding these imports of VueRouter and router.

import VueRouter from 'vue-router' 
import router from './router'

Register the Vue-Router after `Vue.config`.

Vue.use(VueRouter)

Modify new Vue to be like this.

 new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

List of Boards using Bootstrap-Vue

Before create or show data to the views, we have to add Bootstrap-Vue. Type this command to install the module.

npm i bootstrap-vue

Next, open and edit `src/main.js` then add these imports of BootstrapVue and Bootstrap stylesheet.

import BootstrapVue from 'bootstrap-vue' 
import 'bootstrap/dist/css/bootstrap.css' 
import 'bootstrap-vue/dist/bootstrap-vue.css'

Add this line after `Vue.config`.

Vue.use(BootstrapVue);

Now, open and edit src/components/BoardList.vue then add these lines of codes that contain Bootstrap-Vue templates and a method to get the list of data from Firebase.

 <template>
  <b-row>
    <b-col cols="12">
      <h2>
        Board List
        <b-link href="#/add-board">(Add Board)</b-link>
      </h2>
      <b-table striped hover :items="boards" :fields="fields">
        <template slot="actions" scope="row">
          <b-btn size="sm" @click.stop="details(row.item)">Details</b-btn>
        </template>
      </b-table>
    </b-col>
  </b-row>
</template>
 
<script>
 
import firebase from '../Firebase'
import router from '../router'
 
export default {
  name: 'BoardList',
  data () {
    return {
      fields: {
        title: { label: 'Title', sortable: true, 'class': 'text-left' },
        actions: { label: 'Action', 'class': 'text-center' }
      },
      boards: [],
      errors: [],
      ref: firebase.firestore().collection('boards'),
    }
  },
  created () {
    this.ref.onSnapshot((querySnapshot) => {
      this.boards = [];
      querySnapshot.forEach((doc) => {
        this.boards.push({
          key: doc.id,
          title: doc.data().title
        });
      });
    });
  },
  methods: {
    details (board) {
      router.push({ name: 'ShowBoard', params: { id: board.key }})
    }
  }
}
</script>
 
<style>
  .table {
    width: 96%;
    margin: 0 auto;
  }
</style>

Show Details and Delete Board using Bootstrap-Vue

Open and edit src/components/ShowBoard.vue then add these lines of codes that contain Bootstrap-Vue template components and a method to get single data from Firebase.

 <template>
  <b-row>
    <b-col cols="12">
      <h2>
        Edit Board
        <b-link href="#/">(Board List)</b-link>
      </h2>
      <b-jumbotron>
        <template slot="header">
          {{board.title}}
        </template>
        <template slot="lead">
          Title: {{board.title}}<br>
          Description: {{board.description}}<br>
          Author: {{board.author}}<br>
        </template>
        <hr class="my-4">
        <b-btn class="edit-btn" variant="success" @click.stop="editboard(key)">Edit</b-btn>
        <b-btn variant="danger" @click.stop="deleteboard(key)">Delete</b-btn>
      </b-jumbotron>
    </b-col>
  </b-row>
</template>
 
<script>
 
import firebase from '../Firebase'
import router from '../router'
 
export default {
  name: 'ShowBoard',
  data () {
    return {
      key: '',
      board: {}
    }
  },
  created () {
    const ref = firebase.firestore().collection('boards').doc(this.$route.params.id);
    ref.get().then((doc) => {
      if (doc.exists) {
        this.key = doc.id;
        this.board = doc.data();
      } else {
        alert("No such document!");
      }
    });
  },
  methods: {
    editboard (id) {
      router.push({
        name: 'EditBoard',
        params: { id: id }
      })
    },
    deleteboard (id) {
      firebase.firestore().collection('boards').doc(id).delete().then(() => {
        router.push({
          name: 'BoardList'
        })
      }).catch((error) => {
        alert("Error removing document: ", error);
      });
    }
  }
}
</script>
 
<style>
  .jumbotron {
    padding: 2rem;
  }
  .edit-btn {
    margin-right: 20px;
    width: 70px;
  }
</style>

Add Board using Bootstrap-Vue

Open and edit src/components/AddBoard.vue then add these lines of codes that contain Bootstrap-Vue template components and the method to post data to Firebase.

 <template>
  <b-row>
    <b-col cols="12">
      <h2>
        Add Board
        <b-link href="#/">(Board List)</b-link>
      </h2>
      <b-jumbotron>
        <b-form @submit="onSubmit">
          <b-form-group id="fieldsetHorizontal"
                    horizontal
                    :label-cols="4"
                    breakpoint="md"
                    label="Enter Title">
            <b-form-input id="title" v-model.trim="board.title"></b-form-input>
          </b-form-group>
          <b-form-group id="fieldsetHorizontal"
                    horizontal
                    :label-cols="4"
                    breakpoint="md"
                    label="Enter Description">
              <b-form-textarea id="description"
                         v-model="board.description"
                         placeholder="Enter something"
                         :rows="2"
                         :max-rows="6">{{board.description}}</b-form-textarea>
          </b-form-group>
          <b-form-group id="fieldsetHorizontal"
                    horizontal
                    :label-cols="4"
                    breakpoint="md"
                    label="Enter Author">
            <b-form-input id="author" v-model.trim="board.author"></b-form-input>
          </b-form-group>
          <b-button type="submit" variant="primary">Save</b-button>
        </b-form>
      </b-jumbotron>
    </b-col>
  </b-row>
</template>
 
<script>
 
import firebase from '../Firebase'
import router from '../router'
 
export default {
  name: 'AddBoard',
  data () {
    return {
      ref: firebase.firestore().collection('boards'),
      board: {}
    }
  },
  methods: {
    onSubmit (evt) {
      evt.preventDefault()
 
      this.ref.add(this.board).then((docRef) => {
        this.board.title = ''
        this.board.description = ''
        this.board.author = ''
        router.push({
          name: 'BoardList'
        })
      })
      .catch((error) => {
        alert("Error adding document: ", error);
      });
    }
  }
}
</script>
 
<style>
  .jumbotron {
    padding: 2rem;
  }
</style>

 Edit Board using Bootstrap-Vue

Open and edit src/components/EditBoard.vue then add these lines of codes that contain Bootstrap-Vue template components and Vue method to get or post data from or to Firebase.

<template>
  <b-row>
    <b-col cols="12">
      <h2>
        Edit Board
        <router-link :to="{ name: 'ShowBoard', params: { id: key } }">(Show Board)</router-link>
      </h2>
      <b-jumbotron>
        <b-form @submit="onSubmit">
          <b-form-group id="fieldsetHorizontal"
                    horizontal
                    :label-cols="4"
                    breakpoint="md"
                    label="Enter Title">
            <b-form-input id="title" v-model.trim="board.title"></b-form-input>
          </b-form-group>
          <b-form-group id="fieldsetHorizontal"
                    horizontal
                    :label-cols="4"
                    breakpoint="md"
                    label="Enter Description">
              <b-form-textarea id="description"
                         v-model="board.description"
                         placeholder="Enter something"
                         :rows="2"
                         :max-rows="6">{{board.description}}</b-form-textarea>
          </b-form-group>
          <b-form-group id="fieldsetHorizontal"
                    horizontal
                    :label-cols="4"
                    breakpoint="md"
                    label="Enter Author">
            <b-form-input id="author" v-model.trim="board.author"></b-form-input>
          </b-form-group>
          <b-button type="submit" variant="primary">Update</b-button>
        </b-form>
      </b-jumbotron>
    </b-col>
  </b-row>
</template>
 
<script>
 
import firebase from '../Firebase'
import router from '../router'
 
export default {
  name: 'EditBoard',
  data () {
    return {
      key: this.$route.params.id,
      board: {}
    }
  },
  created () {
    const ref = firebase.firestore().collection('boards').doc(this.$route.params.id);
    ref.get().then((doc) => {
      if (doc.exists) {
        this.board = doc.data();
      } else {
        alert("No such document!");
      }
    });
  },
  methods: {
    onSubmit (evt) {
      evt.preventDefault()
      const updateRef = firebase.firestore().collection('boards').doc(this.$route.params.id);
      updateRef.set(this.board).then((docRef) => {
        this.key = ''
        this.board.title = ''
        this.board.description = ''
        this.board.author = ''
        router.push({ name: 'ShowBoard', params: { id: this.$route.params.id }})
      })
      .catch((error) => {
        alert("Error adding document: ", error);
      });
    }
  }
}
</script>
 
<style>
  .jumbotron {
    padding: 2rem;
  }
</style>

Run and Test Vue.js Firebase Firestore Web Application

This time to test all complete the Vue.js and Firebase Firestore Database Stack CRUD web application. Type this command to run again this web application.

yarn serve


And here the application looks like, you can test all CRUD functionality.

That it's, the Vue.js Firebase Tutorial: Build Firestore CRUD Web Application. You can find the working source code from our GitHub.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

The Complete JavaScript Course 2019: Build Real Projects!

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

Nuxt.js - Vue.js on Steroids

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

Build a Progressive Web App In VueJs

Build a CMS with Laravel and Vue

Beginner’s Guide to Vue.js


Suggest:

Here are 380 Ivy League courses you can take online right now for free

Most Popular JavaScript Frameworks 2019 - I'm Programmer

Building a Video Blog with Gatsby and Markdown (MDX)

How to check if Checkbox is Checked or not using Plain JavaScript

A Beginner Guide To Node.js (Basic Introduction To Node.js)

How to create Restful CRUD API with Node.js MongoDB and Express.js