Malo Marrec
Malo Marrec

Reputation: 609

Firebase + Vue: Disconnected at refresh despite setting persistence

I am using Vue and firebase to build an authentication mechanism. Every time I refresh the page, the authentication is dropped, and I am redirected to the login page.

I tried setPersistence(firebase.auth.Auth.Persistence.SESSION) as per the documentation. I also implemented a few of the tips of this reddit thread. I am still being redirected, and I noticed that on refresh, the auth.onAuthStateChanged((user) => {}) callback has user = null.

I am a bit stuck. Apologies if this is a newbie question.

firebase.js

import * as firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/firestore'

const firebaseConfig = {
  apiKey: process.env.VUE_APP_API_KEY,
  ...
};

firebase.initializeApp(firebaseConfig)

// utils
const db = firebase.firestore()
const auth = firebase.auth()
auth.setPersistence(firebase.auth.Auth.Persistence.SESSION)


// export utils/refs
export {
  db,
  auth
}

main.js

import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify';
import router from './router/index'
import { store } from './store'
import { auth } from './firebase'

Vue.config.productionTip = false

let app

auth.onAuthStateChanged((user) => {
  if (!app) {
    app = new Vue({
      router,
      store,
      vuetify,
      render: h => h(App)
    }).$mount('#app')
  }
  if (user) {
    store.dispatch('fetchUserProfile', user)
    store.commit('setEmail', user.email)
  }
  })

router/index.js

import Vue from 'vue';
import Router from 'vue-router';
import Login from '../components/Login'
import Dashboard from '../components/Dashboard'
import { auth } from '../firebase'

Vue.use(Router)

const router = new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes: [
      {
          path: '/login',
          name: 'login',
          component: Login,
          meta: {
            disableNavBar: true
          }
      },
      // ... other routes removed for brevity
      {
          path: '/dashboard',
          name: 'Dashboard',
          component: Dashboard,
          meta: {
            requiresAuth: true
        }
      },
    ]
});

router.beforeEach((to, from, next) => {
  const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
  if(to["path"] !== from["path"]){
    if(requiresAuth){
      auth.onAuthStateChanged(function(user) {
        if (user) {
          console.log("Logged in", user) 
          next();
        } else {
          console.log("Here", user) //this logs user = null on refresh 
          next('/login')
        }
      });
    } else {
      next();
    }
  }
})

export default router

Upvotes: 3

Views: 1550

Answers (2)

Malo Marrec
Malo Marrec

Reputation: 609

I feel very stupid now, sharing this here as it might come handy to people facing this issue.

  1. It turns out that I had a logout function in one of my unused components.vue. Even though it was never used by my application, it was initialized by vue. Each time that happened (meaning, on refresh), the component would be initialized, the script would be executed, and a store.dispatch("logout") would be ran. That caused a lot of useless redirections, on top of the user session being set to null.

I randomly stumbled upon that leftover code by searching for "logout" in my codebase out of despair about the issue. "Damn something must be logging me out". That something was just my own neglect.

  1. That being fixed, setting firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION) works fine.

To those that took the time to answer this question, thank you and sorry :). In case someone stumbles upon this question, and had the same root cause, glad this helped.

Upvotes: 2

roshnet
roshnet

Reputation: 2073

Instead of using SESSION as the auth persistence mode, you need to use LOCAL to make sure the session persists even after closing/refreshing the browser tab or window.

So, next to your firebase.initializeApp(), you could add this -

firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)

Upvotes: 0

Related Questions