Vue Js for beginners part 6,Vue routing,guards with Firebase authentication
Tags: javascript, vue, firebase, nosql
Published: 2021-05-21 15:16:21

This is a sequel to my [VueJs for BeginnersPart5](https://dev.to/tanzimibthesam/vue-js-for-beginners-part-5-vue-routing-route-links-name-routes-route-params-1963) Firebase is a tool made by Google for making mobile and web applications.It can be termed as **Backend as a service** when you are are working with a programming language which requires setting up a server,database etc but with Firebase with minimal setup you can get a backend up and running.Its has a nosql database.
**Note one thing: Firebase is definitely not the best solution and it has its cons too but here to make several things clear about Vue authentication we will explain it.
**For Firebase you need to have a google account**
If you go to `https://firebase.google.com/` if you are logged in from any gmail account you will see 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cifqd44vxghpioc2vkqd.png)
**Click the console from here**
When you click the console you will see
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tplw9mj58a4xw9799izr.png)
From here you will select **Create a Project**
After clicking you will see something like this put name of your project 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxxhsju4dg009o86zs7d.png)
In next step you will get this
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rr9282nldc2r7i8ki3th.png)

Just click on Create Project.Next this will appear 
Here I have selected United States.Click Create project 

You project will will be created It might take a few minutes.
Then if you go to `https://console.firebase.google.com/`
You can see ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bxhid8gd2hrcsal0got7.png)
Click on projects name and get started. 
After clicking you will see 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vkyah9w2ios1cnr4u2oq.png)
Assign a nick name and click register app. Then go to `console.firebase.google.com`
If you dont see this you might see this if you have already made a project previously in Firebase from there 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85q3ig6zvr8r1oyz0orq.png)

You will see list of firebase projects in `console.firebase.google.com`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gpq1l5wx1onh2ekjtjcf.png)
Click your desired project here I am clicking on vue-router
Then you will see 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a8diwv7q0zluuguh43mz.png)
From here on left select **FireStore** like pointed above. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvy3ytyg92hiw8khy7q6.png)
From here we need to select `Create Database`
After selecting create database you will see           **Security rules for Cloud Firestore**  ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jvws80450vlvvjud10zk.png)    Select test mode for now                   
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3u6s638vf7qpday8rukk.png)
 
After you click enable you are done setting up Firebase.Go to `console.firebase.google.com`
If from projects you go to vue router and click on Cloud firestore on left then you will see ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ja6q1r83xqvrak061uz4.png)

In our vue project go to cli and run `npm install firebase`
Create a folder named config and inside it create a file named firebase.js
Now go to `console.firebase.google.com` Then select your project from here select 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jfygzk5k3zqups62a148.png)

While you click it you can surely go to ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7hxg7w3vo3yv1o2tc1it.png)
If we click on settings icon we will see 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/840y5ny3i2wywsynovqj.png)
Then it will take go to projects setting page if you scroll down below the page you will see
I have blurred out the confidential info but you will have your one
 ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvly6sitf3ggm51hhfz1.png)
Here you will select the config and copy and paste all. Next you will go to config/firebase.js 
```
import firebase from 'firebase'
import 'firebase/store'
import 'firebase/auth'
//I jave left it blank you will copy and paste it from your firebase config mentioned in pic above
const firebaseConfig = {
    apiKey: "",//
    authDomain: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
  };

firebase.initializeApp(firebaseConfig)

const db=firebase.firestore();
//Get access to firebase database
const appAuth=firebase.auth();
//get access to authentication in firebase

export {db,appAuth}
```
I will create a Login.vue and Register.vue components in components folder
**Login.vue**
This form is from [W3school](https://www.w3schools.com/howto/howto_css_login_form.asp). Here is how it will be 
```
<div class="container">
    <label for="uname"><b>Username</b></label><br>
    <input type="text" placeholder="Enter Username" name="uname" required><br>

    <label for="psw"><b>Password</b></label><br>
    <input type="password" placeholder="Enter Password" name="psw" required><br>
        
    <button type="submit">Login</button>
    <label>
      <input type="checkbox" checked="checked" name="remember"> Remember me
    </label>
  </div>

  <div class="container" style="background-color:#f1f1f1">
    <button type="button" class="cancelbtn"><router-link :to="{name:'Register'}" class="cancelbtn">Register</router-link></button>
    <span class="psw"></span>
  </div>
</form>
```
**Style.css**
All css here will be in `assets/css/style.css` I have created a style.css file inside css folder of asset directory
To make style work across all component in src/main.js
`import '../src/assets/css/style.css'`
The `Register.vue` will be the same. If you want full form with style click [here](https://codepen.io/TanzimIb/pen/abJpMQx)

**Change / directory to Login**
So we want that when our app loads instead of home directory we see login page 
just go to router/index.js we will do this 
`{
    path: '/',
    name: 'login',
    component: Login
  },
` 
Now if we see on home page we see the login form 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qh2l808q1k9jzqgcmxp.png)
**Set up way of authentication** 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xa647lzb1erv1fhur9o3.png)
As you see in the picture on left you need to click authentication 
in next step you will see 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/098l7771ic9oni1zysj0.png)
From here click set signin method 
Then after click you will see a wide range of options.here I will show email password 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2llsvw8qa7zsjwrl73d.png)
**To enable it**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0xzdbzg0z08qln1q9sa.png)
**Router replace**
In **Register.vue**
```
<template>
    <h2>Register Form</h2>

<form @submit.prevent="handleSubmit">
 

  <div class="container">
    <label for="uname"><b>Email</b></label><br>
    <input type="text" placeholder="Enter Username" v-model="email" required><br>

    <label for="psw"><b>Password</b></label><br>
    <input type="password" placeholder="Enter Password" v-model="password" required><br>
        
    <button type="submit" class="mainbutton">Register</button>
    
  </div>

  <div class="container" style="background-color:#f1f1f1">
     <button type="button" class="cancelbtn">
       <router-link class="cancelbtn" :to="{name:'Login'}">Already have an account?Login</router-link>
        
        </button>
  
  </div>
</form>
</template>

<script>
import { appAuth,db } from '../config/firebase'
    export default {
        data(){
            return{
               email:'',
               password:'',
            }
        },
        methods:{
               async handleSubmit(){
       try {
           
            const user=await appAuth.createUserWithEmailAndPassword(this.email,this.password);
            
            console.log(user);
             this.$router.replace({name:'Home'})
            return user;
            
           
       } catch (error) {
           console.log(error);
           
       }
      
      }}
        
    }
</script>

```
Here we need to put `v-model="email"` and password" and `v-model="password"` in both email and password input fields.
`appAuth.createUserWithEmailAndPassword(this.email,this.password)`
 this is the method of registation in firebase
`this.$router.replace({name:'Home'})` is what takes us to Home directory. 
in **Login.vue**
```
<template>
    <h2>Login Form</h2>

<form @submit.prevent="handleSubmit">
 

  <div class="container">
    <label for="uname"><b>Email</b></label><br>
    <input type="text" placeholder="Enter Username" v-model="email" required><br>

    <label for="psw"><b>Password</b></label><br>
    <input type="password" placeholder="Enter Password" v-model="password" required><br>
        
    <button type="submit" class="mainbutton">Register</button>
    
  </div>

  <div class="container" style="background-color:#f1f1f1">
    <button type="button" class="cancelbtn">
        <router-link class="cancelbtn" :to="{name:'Register'}">Dont have an account?Register</router-link>
        
        </button>
  
  </div>
</form>
</template>

<script>
import { appAuth,db } from '../config/firebase'
    export default {
        data(){
            return{
               email:'',
               password:'',
            }
        },
        methods:{
               async handleSubmit(){
       try {
           
            const user=await appAuth.signInWithEmailAndPassword(this.email,this.password);
             
            console.log(user);
            if(user){
                  this.$router.replace({name:'Home'})
            }
            
            return user;
            
           
       } catch (error) {
           console.log(error);
           
       }
      
      }}
        
    }
</script>
```
Its the same it takes us to the home directory when we login with proper credentials.
in **Home.vue**
```
<template>
  <div class="home">
        <div>Welcome to Home Page</div>
        <div>
          <button @click.prevent="logOut">
            Logout
          </button>
        </div>
  </div>
</template>

<script>
import { appAuth } from '../config/firebase';
export default {
  methods:{
     async logOut(){
         try {
           const logout=await appAuth.signOut();
           console.log(logout);
           this.$router.replace({name:'Login'})
         } catch (error) {
           console.log(error);
           
         }
       }
  }

}
</script>
```
Here we logout but we are redirected to Login page 
**Route Guard**
Its a way whether we decide whether the user can access certain routes based on whether the user is authenticated or not.
Now if we see we are authenticated we can still enter Login route and even when we are not authenticated we can still enter Home.vue. So that needs to be stopped.


`Make auth guard so only authenticated users can enter the home route`
`In router folder index.js file`
`//auth guard
const requireAuth=(to,from,next)=>{
  let user=appAuth.currentUser
  if(!user){
    next({name:'Login'})
  }else{
    next()
  }
}
`
in **Home** route this is how we will write 
```
 {
    path:'/home',
    name:'Home',
    component:Home,
    beforeEnter:requireAuth
  }
```
As a result now only authenticated users can enter the route
Now there are some Problems
**Problem One**
When you are onto home route and you refresh you redirect back to the login route in your case its the / route and also you can manually go back to the route if you just press /
We will go to main.js file 
**Solution**
```
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import '../src/assets/css/style.css'
import { appAuth } from './config/firebase'
let app

appAuth.onAuthStateChanged(() => {
  if (!app) {
    app = createApp(App)
      .use(router)
      .mount('#app')
  }
})
```
 At first the app is created then mounted to the DOM.Here firebase keeps the app on hold until connection is established with the backend.It first hears whether user is logged in or not that is it observes the change of initial auth state change. It is not render unless connection is established with the backend.

Now when we refresh or go back it keeps us on home page.

**Problem two-It still redirects us to Login  and register routes when we enter them manually** 
**Solution go to router folder in index.js file**
```
const notrequireAuth=(to,from,next)=>{
  let user=appAuth.currentUser
  if(user){
    next({name:'Home'})
  }else{
    next()
  }

}
```
So here we see the function is that if user is authenticated he will go to Home route and if he is not than to other 
```
{
    path: '/',
    name: 'Login',
    component: Login,
    beforeEnter:notrequireAuth
  },
  
  {
    path:'/register',
    name:'Register',
    component:Register,
    beforeEnter:notrequireAuth
  }
```
So its a huge blog and it covers a lot you need to know about Vue routing.Hopefully will cover Vuex in next part.