Невозможно получить currentUser при загрузке

При попытке проверить, подписан ли пользователь через firebase.auth().currentUser следующим образом:

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

Всякий раз, когда я обновляю страницу или перемещаюсь по указанному выше элементу, возвращается значение null (хотя я только что вошел в систему).

Странно, что если я запишу

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

Я не знаю, что здесь происходит. Я использую React и Redux, но это не имеет значения, я бы сказал.

Есть ли небольшая задержка, когда firebase инициализируется, и вы не можете получить доступ к currentUser? Если да, то как я могу увидеть его в выводе журнала firebase.auth()?

Ответ 1

Это часто задаваемый вопрос. https://firebase.google.com/docs/auth/web/manage-users Вам нужно добавить наблюдателя в onAuthStateChanged, чтобы обнаружить начальное состояние и все последующие изменения состояния,

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

Ответ 2

Лучший способ всегда иметь доступ к currentUser - это использовать vuex и 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);
    }
});

Единственная проблема, описанная выше, заключается в том, что если пользователь нажимает кнопку "Обновить" в браузере, состояние vuex будет выброшено, и вам придется ждать, пока onAuthStateChange снова сработает, поэтому при попытке доступа к currentUser вы получаете значение null.

Секрет приведенного выше кода, работающего все время, заключается в использовании состояния vuex-persisted.

В вашем файле 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();
    }
  }
})

Теперь вы можете защитить маршруты в вашем маршрутизаторе, как в примере кода ниже.

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

  // On component load.
  componentDidMount = () => this.getAuthStatus();

  // Get firebase auth status.
  getAuthStatus = () => {
    firebase.auth().onAuthStateChanged((resp) => {

        // Pass response to a call back func to update state
        this.updateUserState(resp);
    });
  }

  // update state
  updateUserState = (resp) => {
     this.setState({
         user: resp
     })
  }

  // Now you can validate anywhere within the component status of a user
  if (this.state.user) { /*logged in*/}

Ответ 4

firebase.auth().onAuthStateChanged(function(user) {
    if (user) {

      var user = firebase.auth().currentUser;


      if(user != null){ 
        var io=user.uid;
        window.alert("success "+io);




      }

    } else {
      // No user is signed in.
      Window.reload();

    }
  });

сначала проверьте, существует ли пользователь, затем получите его по

firebase.auth(). currentUser.uid

Ответ 5

Это очень легко решить! Вы можете использовать последнюю версию firebase.js, например.. найти ее в вашей настройке Firebase Web..

 <script src="https://www.gstatic.com/firebasejs/5.4.2/firebase.js"> . </script> 

Надеюсь, это будет решено!