Skip to main content

Command Palette

Search for a command to run...

Firebase Authentication and Vue Router

Adding Route Guard with Firebase Auth to Vue Application

Published
3 min read
Firebase Authentication and Vue Router
A

I am a Frontend Developer and Technical Writer. I love helping other developers understand difficult concepts through writing. If you have any questions regarding tech, or you just want to connect, message me on any of my socials, be sure I will get back to you as soon as possible.

Describing the problem

I struggled with something throughout yesterday, I added Firebase auth to my Vue project, which is quite easy to do, but I encountered a major challenge when I was implementing this with Vue route guard.

Well, I added the route guard and everything worked well, but I found out that if I refresh the page after I'm logged in, the app will take me back to the login page, because at the time the app is mounted, the currentUser property is still null, so the app assumes the user is not logged in and takes me back to the login in page.

As simple as this may sound, this is a common problem that is faced by a lot of Vue developers, especially those that are implementing Firebase auth for the first time. Worst of all, it is very difficult to find a blog post or Youtube tutorial that covers this problem properly. So in this guide, I will show you how I solved this problem.

This is not an article on Firebase auth as there are already a lot of articles and videos that cover the topic. This is just a way for me to show the part that most of the articles and videos out there are missing. I hope you find it helpful.

The Solution

At this point, you already have your Vue Firebase auth setup. Follow these simple steps to properly add route guard to your project:

  • We'll use the meta property authNeeded to mark the route we want to guard. Open your route/index.js file and add the following code:
{
        path: '/',
        name: 'home',
        component: TodolistView,
        meta: {
          authNeeded: true
        }
      },

Replace the path, name and component with the path, name and component you want to guard.

  • We need to tell our application to wait and check if the currentUser is not null before deciding the path of the application the render. Let's do that below:
import { getAuth, onAuthStateChanged } from "firebase/auth"
const auth = getAuth() 
function getCurrentUser() {
  return new Promise((resolve, reject) => {
    const unsubscribe = onAuthStateChanged(auth, (user) => {
        unsubscribe()
        resolve(user)
      },
      reject
    )
  })
}

The code above will return a new Promise and set it to the currentUser once it resolves. The onAuthStateChanged from Firebase will always trigger the callback function with either the user object if the user is logged in in or null if the user is not logged in. After this, we unsubscribe to not listen to any further change.

  • Finally, we need to use the beforeEach guard to protect the route and make sure that only the paths that need authentication await this method. Below is the implementation:
router.beforeEach( async (to) => {
    const authRequired = to.matched.some(record => record.meta.authNeeded)
     if (authRequired && !(await getCurrentUser())) {
      return {path: '/login'}
    }
  });

Conclusion

If you have followed the steps outlined properly, If you refresh your application, you'll notice that everything now works correctly and our application now routes to different sections, depending on whether the user is logged in or not.

Vue route guard from Vue Router library

This blog post helped me