Javascript 无法在加载时获取 currentUser

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37883981/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:51:17  来源:igfitidea点击:

Can't get currentUser on load

javascriptfirebasefirebase-authentication

提问by Chris

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

尝试检查用户是否通过firebase.auth().currentUser以下方式登录时:

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).

每当我刷新页面或浏览上述内容时都会返回 null(即使我刚刚登录)。

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.

我真的不知道这里发生了什么。我正在使用 React 和 Redux,但我想说这并不重要。

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()?

firebase 初始化是否有一点延迟,您无法访问 currentUser?如果是这样,我如何在 的日志输出中看到它firebase.auth()

回答by bojeil

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

这是一个常见的问题。 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.
  }
});

回答by PrestonDocks

The best way to always have access to currentUser is to use vuex and vuex-persistedstate

始终访问 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);
    }
});

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.

上面唯一的问题是,如果用户在浏览器上按下刷新,vuex 状态将被丢弃,您必须等待 onAuthStateChange 再次触发,因此当您尝试访问 currentUser 时为什么会得到 null。

The secret to the above code working all the time is to use vuex-persisted state.

上述代码一直工作的秘诀是使用 vuex 持久化状态。

In your store.js file

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

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

回答by yue

A simple way is to add a pending state.

一个简单的方法是添加一个挂起状态。

Here is a react example using hooks:

这是一个使用钩子的反应示例:

// useAuth.ts

// 使用Auth.ts

import { useState, useEffect } from 'react'
import { auth } from 'firebase'

export function useAuth() {
  const [authState, setAuthState] = useState({
    isSignedIn: false,
    pending: true,
    user: null,
  })

  useEffect(() => {
    const unregisterAuthObserver = auth().onAuthStateChanged(user =>
      setAuthState({ user, pending: false, isSignedIn: !!user })
    )
    return () => unregisterAuthObserver()
  }, [])

  return { auth, ...authState }
}

// SignIn.tsx

// 登录.tsx

import React from 'react'
import { StyledFirebaseAuth } from 'react-firebaseui'
import { useAuth } from '../hooks'

export default function SignIn() {
  const { pending, isSignedIn, user, auth } = useAuth()

  const uiConfig = {
    signInFlow: 'popup',
    signInOptions: [
      auth.GoogleAuthProvider.PROVIDER_ID,
      auth.FacebookAuthProvider.PROVIDER_ID,
    ],
  }

  if (pending) {
    return <h1>waiting...</h1>
  }

  if (!isSignedIn) {
    return (
      <div>
        <h1>My App</h1>
        <p>Please sign-in:</p>
        <StyledFirebaseAuth uiConfig={uiConfig} firebaseAuth={auth()} />
      </div>
    )
  }

  return (
    <div>
      <h1>My App</h1>
      <p>Welcome {user.displayName}! You are now signed-in!</p>
      <a onClick={() => auth().signOut()}>Sign-out</a>
    </div>
  )
}

回答by Kidali Kevin

  // 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*/}

回答by ali remaity

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

    }
  });

first check if user exist then get it id by

首先检查用户是否存在,然后通过

firebase.auth().currentUser.uid

firebase.auth().currentUser.uid