Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't get currentUser on load

When trying to check if a user is signed in via firebase.auth().currentUser like this:

if (firebase.auth().currentUser === null) {   console.log('User not signed in'); } 

Whenever I refresh the page, or navigate around the above returns null (even though I have just logged in).

The weird thing is, that if I log

console.log(firebase.auth().currentUser) // This returns null console.log(firebase.auth()) // Here I can inspect the object and currentUser exists...! 

I don't really know what's going on here. I'm using React and Redux, but it shouldn't really matter I'd say.

Is there a small delay where the firebase initialises and you can't access the currentUser? If so, how can I see it in the log output of firebase.auth()?

like image 347
Chris Avatar asked Jun 17 '16 14:06

Chris


2 Answers

This is a commonly asked question. https://firebase.google.com/docs/auth/web/manage-users You need to add an observer to onAuthStateChanged to detect the initial state and all subsequent state changes,

firebase.auth().onAuthStateChanged(function(user) {   if (user) {     // User is signed in.   } else {     // No user is signed in.   } }); 
like image 139
bojeil Avatar answered Oct 21 '22 13:10

bojeil


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()     } }) 
like image 33
PrestonDocks Avatar answered Oct 21 '22 12:10

PrestonDocks