Build a Vue App with Firebase Authentication and Database

Build a Vue App with Firebase Authentication and Database

  • 1068

Vue is a progressive framework that is used to build user interfaces for web apps. Unlike other JavaScript frameworks and libraries, Vue was designed to help developer easily adopt it.

Easy to use, powerful and very well documented, Vue’s simplicity and high performance has helped it stand out among giants like React and Angular. Vue is now in its third iteration and received over 119K 🌠 on GitHub!

On the other hand, we have Firebase, Google’s premiere web and mobile application development platform. Firebase provides developers with a long list of tools and services that help developers build high quality apps, grow their user base, and earn more profit.

The main reason developers choose to use Firebase is that it allows us to develop applications without having to worry about the server side. Among its many, many tools and services, I will only be focusing on it’s authentication system, and its new flexible, scalable NoSQL database — Cloud Firestore.

Getting Started

Installing Vue-CLI

Before, we start working on our Vue App, let’s make sure that our system has the proper command installed on it. There are a couple of way which we can choose from in order to build our Vue App. We are going to use the vue-cli tool. To install this tool on our system, open a command terminal and run:

npm install -g vue-cli

Now to use this tool to build our Vue project. Another great thing about this tool is that it allows use to choose from various templates such as webpack, pwa, webpack-simple, simple, browserify, and browserify-simple. For our project in this post, we will use the webpack template.

$ vue init webpack vue-app

The above command will create a new project directory in your system named vue-app. Once you enter this command, vue-cli will ask you to provide

  • Project name (hit “enter)
  • Project description (hit “enter”)
  • Author (change it if you want to)
  • Vue build (Runtime + Compiler)
  • Install vue-router? (Press “Y”)
  • Use ESLint to lint your code? (Press “N”)
  • Set up unit tests (Press “N”)
  • Setup e2e tests with Nightwatch? (Press “N”)

The final thing that vue-cli will ask you if you would like it to install the packages for you using NPM or Yarn. You can select anything you want.

Once vue-cli is done building the project directory and installing the packages. Open the folder using any code editor (I ❤ VS Code). Here you will find a folder named src. This is where the “source” code of our app will be placed.

In this post, we will start by writing the code for our App’s components, then link them together using router, then work on the code of App.vue and main.js file.

We also need to install a couple of additional dependencies like firebase (obviously) and vuefire, another Firebase related package that will help use the Cloud Firestore database.

$ npm install firebase vuefire

Components

Comics

Let’s start with the component that users will get to see once they are successfully authenticated. I have named this file as Comics.vue and placed it inside the components folder.

The .vue file is divided into three parts: the template, script, and style. The template contains the HTML that will be rendered on the browser, script contains the JavaScript code, and the style will contain the style code. To keep this post short and to the point, I am only going to talk about the template and script. But don’t worry, I will share the final version of the code at the end of this post.

Let’s start by writing the template section as shown below:

Take a look at the first button tag. It has an attribute called v-on:click. The v-on directive is used to listen to any DOM events and run JavaScript code. Here the v-on directive will listen for a “click” on the button, then run the logout function that will be defined in the script section of the same file.

Next, we take a look that the article tag. It has the v-for directive, which like a normal for loop is used here to render a list of items. Here, we take a “comic” from a list of “comics” and renders each of them.

Another thing to note is the :key. This is important here because without it Vue will throw an error saying that each item in the list requires a unique identifier, which in this case is defined by the :key.

Then, in the form tag, we see the @submit directive. This is used to tell Vue what JavaScript code to run when the form is submitted. Here, it will run the addComic function with the name and image as arguments. These arguments are defined by the input elements inside the same form. We use the v-model to define where the user’s input is to be stored once the form is submitted.

Alot of it will not make much sense without taking a look at the script section of this file. So below the template section, write the following code:

We start by importing the Firebase library. We will also import the db const that we will define in the main.js file later on. Next, we will write all the JavaScript code for this inside a default export statement, starting with this component’s name as Comics. After that, we will write the data, and this is where we define the name and image that we used inside the input in the template section. We will also define the comics collection as an empty array.

After that, we define the firestore database. All we do is here create a collection named comics inside the Firestore database and order it by its data of creation.

We will then define the functions that we have used in the template. First one is the addComic, where we are creating a new document inside the comics collection. Each document will have three fields — name, image, and createdAt,

If we are able to create an entry, then we should be able to delete it as well. This is achieved by the deleteComic function that takes in the id as an argument and uses it to delete a doc from the comics collection.

Finally, we have the logout function, which will use Firebase to sign out of the of the app, and redirect the user to the login page.

But we have not created the login page… yet.

Login

This is the first page where a user will be taken to when they open the app. Let’s start by creating a new file named Login.vue and write its template section as shown below:

Looks similar to previous page of Comics, the only thing new here is that we are using the router-link to takes the user to the signup page.

But there is more to this page than that. This is also where the user get authenticated and enters the app. This is done using the login method that is connected to the v-on:click method of the Enter button. Let’s define it inside the script section of this file:

Inside the Firebase, we have an auth function that takes care of everything related to authentication. Since we are using email and password to authenticate a user, we use the signInWithEmailAndPassword function and pass it the email and password provided by the user to check if the user is eligible to enter the app. If they are, then app takes us to the comics page, and if not, then we get the error.

But how does a user enter the app, if they are visiting it for the first time, and they do not have any account created. Creating of new accounts can be taken care of by a new page called signup.

Signup

Create another file named SignUp.vue and write its template section as shown below:

Nothing new here. The only thing of interest here is the v-on:click directive on the Sign Up! button. Let’s get down to the script section and write the signup method for this button.

The signUp method also uses Firebase’s auth() function to create a new user with the email and password provided by the user. If firebase is able to create this new user, the app redirects back to the login page.

With that we are done with building our components. Now we need to connect them to another. We have been talking about how the app will take us from one page to the other. But we have yet to implement these routes in the router folder of our app.

Routes

The router folder has only one file named index.js. This is where all the routes of our app will be defined as shown below:

This is a regular JavaScript file, so we start with import statements for Vue, Router, firebase, Login, SignUp and Comics.

Then we tell Vue to use the Router in this file, and create a new instance of Router that contains an array called routes which defines all the routes needed for the app.

But there only other thing left to do. We need to make sure that an unauthenticated user cannot access any private part of our app. This can be done using the beforeEach function.

Basically, beforeEach check whether the user is authenticated to access the part of the app. Since the /comics page is the only private part of our app, the app will keep us on this page until the user click on the logout button. But if the user is not authenticated and tries to enter the the comics page by entering the URL, beforeEach will keep us on the login page.

App

This is the simplest file in our app. The most important part of this file is the router-view component. This is a functional components that renders the matched component for the given path.

What this means is that this component user the router to check which page to render on the browser.

Main

Finally we come to the main.js file. This file is most important as this is where we will initialize the firebase for our app.

Start by writing the import statements for Vue, App, router, VueFire firebase, and firebase/firestore.

import Vue from 'vue'
import App from './App'
import router from './router'
import VueFire from 'vuefire'
import firebase from 'firebase/app'
import 'firebase/firestore'

Then tell Vue to use the VueFire library.

Vue.use(VueFire)

Now we come to the most important part — initializing Firebase. But before we do that, we need to create an app in the Firebase console.

Let’s do by first going to Firebase console in our browser. Once there, click on “Get Started”.

Then click on “Add project”.

You will then be asked to give it a name, you can name it anything you like, and you are not restricted to using the same name as your Vue app’s.

Once you click on “Create project”, Firebase will take some time to create the Firebase project. Once done you should get something like this:

You will notice the </> icon. Click on it to get the credentials. Copy them and insert them into the main.js file as shown below:

firebase.initializeApp({
  apiKey: '',
  authDomain: '',
  databaseURL: '',
  projectId: '',
  storageBucket: '',
  messagingSenderId: ''
}) 

Firestore needs one extra line of configuration. If you recall back in the Comics.vue file, we imported db from 'main.js' file. db actually resembles the Firestore database and is defined as shown below:

export const db = firebase.firestore()

Everything else in the main.js file can be left as it is:

Vue.config.productionTip = false
new Vue({
  el: '#app',
  router,
  components: {App},
  template: '<App/>
})

We are almost done with our App, all that left to do is configure the Authentication and Database in the Firebase Console.

Firebase

Authentication

Back in the Firebase Console, click on the Authentication link on the left-hand side of the page. You will then something like this:

Click on Sign-in method and enable Email/Password.

Database

Go back to the Firebase Console and click on Database. Then, click on create database.

You will then be asked to select the security rules. For this app, we will select the rules set by test mode.

And that is it! Our app is now ready! With all the styling, the app should look something like this:

Conclusion

If you have followed this post in its entirety, you are now ready to build your Vue apps with Firebase Authentication and Database. This was a long post, and I would like to thank you for sticking with me till the end.

Feel free to comment, ask anything and suggest your ideas. I’d love to talk.

The next post will be on how to convert this app into a PWA, because I truly believe that PWAs are the next step in web development.

Recommended Reading

How to build PWA w/ Vue CLI 3

Building a Simple Virtual DOM from Scratch

How to Write better VueJS code

10+ Vue.js Directives You Must Know to Maximize Your Productivity

How to Target the DOM in Vue