Vue.js Firebase Tutorial: Build Firestore CRUD Web Application

by Didin J. on Oct 19, 2018 Vue.js Firebase Tutorial: Build Firestore CRUD Web Application

A comprehensive step by step tutorial on build Firestore Database CRUD Web Application using Vue.js and Firebase

A comprehensive step by step tutorial on build Firestore Database CRUD Web Application using Vue.js 2 and Firebase. In this tutorial, we are using a standard Firebase module for Javascript. Starting from the Firebase connection to Firestore Database CRUD (Create, Read, Update, Delete) operation. This tutorial will be similar to the same Firebase Firestore tutorial using React.js. So, we will use the same Firestore Database and Collections.


Table of Contents:


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 the Node.js command line is working (on Windows) or runnable in Linux/OS X terminal.

You can watch the video tutorial from our YouTube channel here. Please like, share, comment, and subscribe to our channel.


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.

Vue 3 Firebase Tutorial: Build Firestore CRUD Web Application - Firebase Console

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

Vue 3 Firebase Tutorial: Build Firestore CRUD Web Application - Project Overview

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

Vue 3 Firebase Tutorial: Build Firestore CRUD Web Application - Security rules

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

Vue 3 Firebase Tutorial: Build Firestore CRUD Web Application - Firestore Database

Click the `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.

Vue 3 Firebase Tutorial: Build Firestore CRUD Web Application - Add Collection

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.

Vue 3 Firebase Tutorial: Build Firestore CRUD Web Application - Vue Welcome Page


Install and Configure the Firebase Module

We use the 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 the 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 the 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.

Vue 3 Firebase Tutorial: Build Firestore CRUD Web Application - Run App

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

That just the basic. If you need more deep learning about MEVN Stack, Vue.js or related you can take the following cheap course:

Thanks!