webentwicklung-frage-antwort-db.com.de

CurrentUser kann nicht geladen werden

Wenn Sie versuchen, zu überprüfen, ob ein Benutzer über firebase.auth().currentUser angemeldet ist, gehen Sie wie folgt vor:

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

Jedes Mal, wenn ich die Seite aktualisiere oder in den obigen Abschnitten navigiere, wird null zurückgegeben (obwohl ich mich gerade angemeldet habe).

Das seltsame ist, wenn ich mich anmelde

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

Ich weiß nicht wirklich, was hier los ist. Ich benutze React und Redux, aber es sollte eigentlich egal sein, würde ich sagen.

Gibt es eine kleine Verzögerung, bei der die Firebase initialisiert wird und Sie nicht auf den aktuellen Benutzer zugreifen können? Wenn ja, wie kann ich es in der Protokollausgabe von firebase.auth() sehen?

29
Chris

Dies ist eine häufig gestellte Frage. https://firebase.google.com/docs/auth/web/manage-users Sie müssen onAuthStateChanged einen Beobachter hinzufügen, um den Anfangszustand und alle nachfolgenden Zustandsänderungen zu erkennen.

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

Der beste Weg, immer Zugriff auf currentUser zu haben, ist die Verwendung von vuex und 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);
    }
});

Das einzige Problem oben ist, dass, wenn der Benutzer im Browser auf "Aktualisieren" drückt, der vuex-Status verworfen wird und Sie warten müssen, bis onAuthStateChange erneut ausgelöst wird. Daher wird beim Versuch, auf currentUser zuzugreifen, "Null" angezeigt.

Das Geheimnis des oben genannten Codes, das immer funktioniert, ist die Verwendung des vuex-beständigen Zustands.

In deiner store.js Datei

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

Sie können jetzt Routen in Ihrem Router wie im folgenden Codebeispiel schützen.

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