In this article, we are going to create a basic authentication with Firebase. Don’t worry if you are new to firebase, we are also going to cover how to create a project with Firebase and grab your web API keys. We are going to create Login, Sign Up, and a Dashboard route to figure out about the firebase authentication.
Setup App with Vue CLI
First, let’s create your project with Vue CLI. If you are familiar with CRA( create-react-app ) then the Vue CLI is similar to CRA to create your project boilerplate with almost zero effort.
npx @vue/cli create firebase-auth
This command will ask you to select a preset to set up your project that you can select either default or manually. We required vue-router to our firebase authentication app. So we are going to selec the manually preset.

The manually preset will help you select more required options such as TypeScript, PWA, Router etc. You need to press the spacebar to select one of these options and up/down arrow key to handle to option. You need to select the Router as its required for our app.

Next, wait for a while until the process complete.
The next step is to create a basic template for Login, Sing Up, and Dashboard routes. We are going to use the bootstrap to quickly set up the layout for the further.
Add Bootstrap Framework to your app
First, let’s add the bootstrap CSS to a recently created project. We need the basic style, so don’t require to add the jQuery and Javascript dependencies for the bootstrap. We can add it through the npm command but to make this process quick, we are going to add it to the public/index.html
file like below.
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
Now, it’s time to create and define the routes and the layouts.
Create Navigation and Routes
First, open the App.vue
file which is located under the project, and then /src directory.
<template>
<div class="navbar navbar-dark bg-primary">
<a class="navbar-brand" href="#">Firebase Auth</a>
<ul class="nav">
<li class="nav-item">
<router-link class="nav-link text-white" to="/">Home</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link text-white" to="/dashboard">Dashboard</router-link>
</li>
<li class="nav-item">
<router-link class="nav-link text-white" to="/login">Login</router-link>
</li>
</ul>
</div>
<div class="container py-4">
<router-view />
</div>
</template>
As you can see, we have defined the route links. Now let’s create 3 files under the /src/views directory i.e. Login.vue
, Signup.vue
and the Dashboard.vue
and open the index.js
file under /src/router directory and add the routes.
const routes = [
{
path: "/",
name: "Home",
component: Home
},
{
path: "/login",
name: "Login",
component: () => import("../views/Login.vue")
},
{
path: "/signup",
name: "Signup",
component: () => import("../views/Signup.vue")
},
{
path: "/dashboard",
name: "Dashboard",
component: () => import("../views/Dashboard.vue"),
meta: {
requiresAuth: true
}
}
];
As you can see in the above codes, that we have used the meta property for the Dashboard route to make the authentication required only for this route.
Now we have to check for the authentication required for every route. Now let’s use the navigation guard to add some conditional logic to check each route.
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
});
router.beforeEach((to, from, next) => {
const authenticatedUser = null;
const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
if ( requiresAuth && ! authenticatedUser ) {
alert("You are not authorized to access this area.");
next("login");
}
else {
next();
}
});
We have used the beforeEach()
guard. For the time being, we are going to add null
for the authenticatedUser variable, later we can use the firebase in place of null. Next, we are accessing the requiresAuth
from the meta property from the currect route. And the final condition to display the alert for the unauthorized access and redirect the user to the login route if the user is not authenticated.
Now let’s give some rest for the logic part and move to the template section for Login.vue
, Signup.vue
and the Dashboard.vue
views.
Let’s Create the Basic Layout
We don’t have much to explain the template section, because it’s just a plain HTML. If you want to HTML part then stay on this section or you can move to the next section.
Login.vue Template

<template>
<div class="row">
<div class="col-12 text-center mb-4">
<h1>Log In</h1>
</div>
<div class="col-sm-5 m-auto">
<form id="login-form">
<div class="row text-left">
<div class="col-sm-12 form-group">
<label for="email">Email Address</label>
<input type="email" id="email" class="form-control form-control-lg">
</div>
<div class="col-sm-12 form-group">
<label for="password">Password</label>
<input type="password" id="password" class="form-control form-control-lg">
</div>
<div class="col-sm-12 text-center form-group">
<button class="btn btn-lg btn-primary px-4">
<span>Login</span>
</button>
</div>
<div class="col-sm-12 text-center form-group mt-5">
<p>Don't have an account? <router-link to="/signup">Sign Up</router-link></p>
</div>
</div>
</form>
</div>
</div>
</template>
Signup.vue Template

<template>
<div class="row">
<div class="col-12 text-center mb-4">
<h1>Sign Up</h1>
</div>
<div class="col-sm-5 m-auto">
<form id="signup-form">
<div class="row text-left">
<div class="col-sm-12 form-group">
<label for="email">Email Address</label>
<input type="email" id="email" class="form-control form-control-lg">
</div>
<div class="col-sm-12 form-group">
<label for="password">Password</label>
<input type="password" id="password" class="form-control form-control-lg">
</div>
<div class="col-sm-12 text-center form-group">
<button class="btn btn-lg btn-primary px-4">
<span>Sign Up</span>
</button>
</div>
<div class="col-sm-12 text-center form-group mt-5">
<p>
Already have an account?
<router-link to="/login">Login</router-link>
</p>
</div>
</div>
</form>
</div>
</div>
</template>
Dashboard.vue Template
<template>
<div class="row">
<div class="col-12">
<h1>Dashboard</h1>
</div>
</div>
</template>
We will come later to the vue project. Time to move to the Firebase part. If you don’t have an account with Firebase then create one or use your existing account details to get the console section.
Create Project with Firebase
We are using a fresh account with the Firebase and this what you can see after getting to the dashboard. So, let’s create your project/container for the app but clicking on the “Create a project” button.

Next, give any suitable name for your project. Now click the “Create a project” button. and name your app whatever you like and press the “Continue” button.

The next screen will be asking to enable Google Analytics for this project. Currently, we don’t require this so Disable it and press the “Create Project” button.


It will take a very small time to prepare the project and press the “Continue” button once it ready to go.

Cool, we have successfully created our project in Firebase.
Add Firebase to our Web Application
Next, we have to access it to our application. As you can see from the below screenshot, Firebase supports multiple platforms to work with. So we have to select the Web Application platform.

Next, We have to add a suitable name and click the “Register app” button.


Firebase will provide you some mandatory configuration that you require to connect your web app with firebase. Copy the provides codes and paste it somewhere cause we are going to use it with our Vue app.

Install Firebase to Vue App
We required to install the Firebase SDK to connect with our Vue app. So, let’s install it.
npm install firebase --save
Now open the main.js file and import firebase with the required configuration provided by Firebase.
import firebase from 'firebase';
....
....
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaxxxxxxxxxxxxxxxxxxxr14",
authDomain: "vue-auth-xxxxx.firebaseapp.com",
databaseURL: "https://vue-auth-xxxxxx.firebaseio.com",
projectId: "vue-auth-xxxx",
storageBucket: "vue-auth-xxxxx.appspot.com",
messagingSenderId: "xxxxxxxx",
appId: "1:xxxxxxx:web:9xxxxxxxxxxxxxx8"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
createApp(App)
.use(router)
.mount("#app");
Make sure to replace your configuration settings correctly.
Signup with Firebase
Now, let’s add the Firebase with Signup.vue
template. First, let’s complete it by attaching the data model and event.
<template>
<div class="row">
<div class="col-12 text-center mb-4">
<h1>Sign Up</h1>
</div>
<div class="col-sm-5 m-auto">
<div v-if="errorMessage !== ''" class="alert alert-danger" role="alert">
{{ errorMessage }}
</div>
<div v-if="successMessage !== ''" class="alert alert-success" role="alert">
{{ successMessage }}
</div>
<form @submit.prevent="signupRequest" id="signup-form">
<div class="row text-left">
<div class="col-sm-12 form-group">
<label for="email">Email Address</label>
<input type="email" id="email" v-model="email" class="form-control form-control-lg">
</div>
<div class="col-sm-12 form-group">
<label for="password">Password</label>
<input type="password" id="password" v-model="password" class="form-control form-control-lg">
</div>
<div class="col-sm-12 text-center form-group">
<button v-bind:disabled="xhrRequest" v-bind:class="{disabled: xhrRequest}" class="btn btn-lg btn-primary px-4">
<span v-if="! xhrRequest">Sign Up</span>
<span v-if="xhrRequest">Please Wait...</span>
</button>
<div v-if="xhrRequest" class="spinner-border text-secondary _loader" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
<div class="col-sm-12 text-center form-group mt-5">
<p>
Already have an account?
<router-link to="/login">Login</router-link>
</p>
</div>
</div>
</form>
</div>
</div>
</template>
<script>
import firebase from "firebase";
export default {
name: "Signup",
data() {
return {
email: "",
password: "",
xhrRequest: false,
errorMessage: "",
successMessage: ""
}
},
methods: {
signupRequest() {}
}
}
</script>
<style scoped>
._loader {
position:relative;
top:6px;
left:10px;
}
</style>
We required the email, password, xhrRequest, errorMessage,
and successMessage
data model to working with. The email
and password
model we require for registering a user. The xhrRequest
model to identify the async request made by Firebase. And the errorMesssage
and successMessage
for displaying the error or success message.
The signupRequest
method we have attached with our Form to submit the email
and password
to the Firebase.
<form @submit.prevent="signupRequest" id="signup-form">
We have also used the binding to attach the CSS class to “Sign Up” button.
<button v-bind:disabled="xhrRequest" v-bind:class="{disabled: xhrRequest}" class="btn btn-lg btn-primary px-4">
The disabled property and the CSS class only works when the xhrRequest
model gets true
.
Let’s move to the next step by adding the Firebase to this Signup Form.
We are not going to add the validation to this form. We have a separate article on Handling Form Validation with Vue.
<script>
import firebase from "firebase";
export default {
name: "Signup",
data() {
return {
email: "",
password: "",
xhrRequest: false,
errorMessage: "",
successMessage: ""
}
},
methods: {
signupRequest() {
let v = this;
v.xhrRequest = true;
v.errorMessage = "";
v.successMessage = "";
firebase
.auth()
.createUserWithEmailAndPassword(v.email, v.password).then(
() => {
v.successMessage = "Register Successfully.";
v.xhrRequest = false;
},
( error ) => {
let errorResponse = JSON.parse(error.message);
v.errorMessage = errorResponse.error.message;
v.xhrRequest = false;
}
);
}
}
}
</script>
First, import the Firebase SDK that provides helpful functions. First, reset the errorMessage
and successMessage
model with an empty value and apply the true
value to the xhrRequest
. Because this method only triggers on the form submit event. Now apply the createUserWithEmailAndPassword()
function provided by Firebase SDK.
firebase.auth().createUserWithEmailAndPassword(email, password).then(successCallback, errorCallback);
You can learn more about the createUserWithEmailAndPassword() for the Firebase doc.
This is not done yet, because when you try to create your first user, you will get the Configuration_Not_Found error.

And this because you have to Enable the Email/Password option from the Sign-in providers. Let’s move to the Firebase Console to Enable it. And find the Authentication section like the below screenshot and click on it.

Now click the “Get Started” button from the next screen.

Now, find the Sign-in method tab and click on it. The tab screen appears with multiple Sign-in providers. Find the Email/Password provider and enable it.


Now, if you try again to register your user then everything works perfectly.

So, this is how the Signup process works. Now move to the login template.
Login with Firebase
The method and data model bindings are similar to the Singup template, so we directly jump to the loginRequest
method.
<template>
<div class="row">
<div class="col-12 text-center mb-4">
<h1>Log In</h1>
</div>
<div class="col-sm-5 m-auto">
<div v-if="errorMessage !== ''" class="alert alert-danger" role="alert">
{{ errorMessage }}
</div>
<div v-if="successMessage !== ''" class="alert alert-success" role="alert">
{{ successMessage }}
</div>
<form @submit.prevent="loginRequest" id="login-form">
<div class="row text-left">
<div class="col-sm-12 form-group">
<label for="email">Email Address</label>
<input type="email" v-model="email" id="email" class="form-control form-control-lg">
</div>
<div class="col-sm-12 form-group">
<label for="password">Password</label>
<input type="password" v-model="password" id="password" class="form-control form-control-lg">
</div>
<div class="col-sm-12 text-center form-group">
<button v-bind:disabled="xhrRequest" v-bind:class="{disabled: xhrRequest}" class="btn btn-lg btn-primary px-4">
<span v-if="! xhrRequest">Login</span>
<span v-if="xhrRequest">Please Wait...</span>
</button>
<div v-if="xhrRequest" class="spinner-border text-secondary loader" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
<div class="col-sm-12 text-center form-group mt-5">
<p>Don't have an account? <router-link to="/signup">Sign Up</router-link></p>
</div>
</div>
</form>
</div>
</div>
</template>
<script>
import firebase from "firebase";
export default {
name: "Login",
data() {
return {
email: "",
password: "",
xhrRequest: false,
errorMessage: "",
successMessage: ""
}
},
methods: {
loginRequest() {
let v = this;
v.xhrRequest = true;
v.errorMessage = "";
v.successMessage = "";
firebase.auth().signInWithEmailAndPassword(v.email, v.password).then(
() => {
this.$router.replace('dashboard')
v.xhrRequest = false;
},
(error) => {
v.errorMessage = error.message;
v.xhrRequest = false;
}
)
}
}
}
</script>
<style scoped>
.loader {
position:relative;
top:6px;
left:10px;
}
</style>
The same step similar to the Signup.vue
template, first import the Firebase SDK and use the built-in function.
firebase.auth().signInWithEmailAndPassword(email, password).then(successCallback, errorCallback);
Redirect the successfully logged in user to the dashboard route with this.$router.replace()
function.
Now, the final step is to slightly modify the navigation guard from index.js
file under the /src/router directory. Replace the authenticatedUser
from null
to firebase.auth().currentUser
.
Make sure to import the Firebase SDK before using the firebase.auth().currentUser.
router.beforeEach((to, from, next) => {
const authenticatedUser = firebase.auth().currentUser;
const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
if ( requiresAuth && ! authenticatedUser ) {
alert("You are not authorized to access this area.");
next("login");
}
else {
next();
}
});
We hope this article will help you to learn the Firebase connection and authentication with Vuejs. If you like this article then please follow us on Facebook and Twitter.