The best way to always have access to currentUser is to use vuex and vuex-persistedstate
//Configure firebase
firebase.initializeApp(firebaseConfig);
//When ever the user authentication state changes write the user to vuex.
firebase.auth().onAuthStateChanged((user) =>{
if(user){
store.dispatch('setUser', user);
}else{
store.dispatch('setUser', null);
}
});
The only issue above is that if the user presses refresh on the browser the vuex state will be thrown away and you have to wait for onAuthStateChange to fire again, hence why you get null when you try to access currentUser.
The secret to the above code working all the time is to use vuex-persisted state.
In your store.js file
import Vue from 'vue'
import Vuex from 'vuex'
import firebase from 'firebase/app'
Vue.use(Vuex)
import createPersistedState from "vuex-persistedstate";
export default new Vuex.Store({
plugins: [createPersistedState()],
state: {
user: null
},
getters:{
getUser: state => {
return state.user;
}
},
mutations: {
setUser(state, user){
state.user = user;
}
},
actions: {
setUser(context, user){
context.commit('setUser', user);
},
signIn(){
let provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider).then(function (result) {
})
},
signOut(){
firebase.auth().signOut();
}
}
})
You can now protect routes in your router as in the code example below.
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import Search from '@/components/Search/Search'
import CreateFishingSite from '@/components/FishingSites/CreateFishingSite'
Vue.use(Router);
import store from './store'
import firebase from 'firebase'
let router = new Router({
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/search/:type',
name: 'Search',
component: Search
},
{
path: '/fishingsite/create',
name: 'CreateFishingSite',
component: CreateFishingSite,
meta: {
requiresAuth: true
}
}
]
})
router.beforeEach(async (to, from, next)=>{
let currentUser = store.state.user;
console.log(currentUser);
let requriesAuth = to.matched.some(record => record.meta.requiresAuth);
if(requriesAuth && !currentUser){
await store.dispatch('signIn');
next('/')
}else{
next()
}
})
console.log(someObject)
will show you a compacted view of the properties of someObject at that moment. But when you expand it by clicking it in the console, it will show you its current values, at the moment of clicking. Soconsole.log(firebase.auth())
will show youcurrentUser: null
, but when you manage to click on it (800 ms later), Firebase has authenticated you andcurrentUser
will have a value. You can try doing it with internet turned off and you'll see it remains null. Or you can doconsole.log({...firebase.auth()})
which will not update its value.