web-dev-qa-db-ja.com

ロード時に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()のログ出力でそれを見ることができますか?

29
Chris

これはよくある質問です。 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.
  }
});
31
bojeil

常に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になる理由です。

上記のコードが常に機能する秘secretは、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
PrestonDocks