web-dev-qa-db-fra.com

Impossible d'obtenir currentUser en charge

Lorsque vous essayez de vérifier si un utilisateur est connecté via firebase.auth().currentUser comme ceci:

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

Chaque fois que je rafraîchis la page ou que je navigue dans les éléments ci-dessus, la valeur est nulle (même si je viens de me connecter).

La chose étrange est que si je me connecte

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

Je ne sais pas vraiment ce qui se passe ici. J'utilise React et Redux, mais cela ne devrait pas vraiment avoir d'importance, je dirais.

Y a-t-il un petit délai où la base de données s'initialise et vous ne pouvez pas accéder à l'utilisateur actuel? Si oui, comment puis-je le voir dans la sortie du journal de firebase.auth()?

29
Chris

Ceci est une question fréquemment posée. https://firebase.google.com/docs/auth/web/manage-users Vous devez ajouter un observateur à onAuthStateChanged pour détecter l'état initial et tous les changements d'état ultérieurs,

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
  } else {
    // No user is signed in.
  }
});
31
bojeil

La meilleure façon d'avoir toujours accès à currentUser est d'utiliser vuex et 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);
    }
});

Le seul problème ci-dessus est que si l'utilisateur appuie sur Actualiser sur le navigateur, l'état vuex sera jeté et vous devrez attendre que onAuthStateChange se déclenche à nouveau, d'où la raison pour laquelle vous obtenez null lorsque vous essayez d'accéder à currentUser.

Le secret pour que le code ci-dessus fonctionne tout le temps est d'utiliser l'état persistant vuex.

Dans votre fichier store.js

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();
    }
  }
})

Vous pouvez désormais protéger les itinéraires de votre routeur comme dans l'exemple de code ci-dessous.

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()
    }
})
3
PrestonDocks