로드에서 현재 사용자를 가져올 수 없습니다.
사용자가 로그인되었는지 확인하려고 할 때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...!
여기서 무슨 일이 일어나고 있는지 잘 모르겠어요.저는 리액트와 리덕스를 사용하고 있지만, 제가 말하는 것은 별로 중요하지 않습니다.
파이어베이스가 초기화되고 현재 사용자에 액세스할 수 없는 약간의 지연이 있습니까?그렇다면 의 로그 출력에서 어떻게 확인할 수 있습니까?firebase.auth()?
이것은 일반적으로 묻는 질문입니다.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.
  }
});
간단한 방법은 보류 중인 상태를 추가하는 것입니다.
다음은 후크를 사용한 반응 예제입니다.
Auth.
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 }
}
사인인 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>
  )
}
currentUser에 항상 액세스할 수 있는 가장 좋은 방법은 vuex 및 vuex 지속 상태를 사용하는 것입니다.
//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 상태가 사라지고 AuthStateChange에서 다시 시작될 때까지 기다려야 하므로 현재 사용자에 액세스하려고 하면 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()
    }
})
Firebase와의 대응을 위해 Auth 경로를 복사하여 붙여넣으려는 경우:
const AuthRoute = ({ component: Component, ...rest }) => {
      const [authenticated, setAuthenticated] = useState(false)
      const [loadingAuth, setLoadingAuth] = useState(true)
      useEffect(() => {
        firebase.auth().onAuthStateChanged((user) => {
          if (user) {
            setAuthenticated(true)
          } else {
            setAuthenticated(false)
          }
          setLoadingAuth(false)
        })
      }, [])
      return loadingAuth ? 'loading...' : (
        <Route
          {...rest}
          render={props =>
            authenticated ? (
              <Component {...props} />
            ) : (
              <Redirect to={{ pathname: '/user/login' }} />
            )}
        />
      )
    }
다음과 같은 세 가지 옵션이 있습니다.
업데이트: 11/26/22
Firebase 9+의 경우 다음을 수행할 수 있습니다.
참고: (이 .auth)는 Auth 개체이며 프레임워크에 따라 다릅니다.
const user1 = await firstValueFrom(authState(this.afa));
const user2 = await firstValueFrom(
  new Observable(observer => onAuthStateChanged(this.afa, observer))
);
const user3 = this.afa.currentUser;
// best option
const user1 = await new Promise((resolve: any, reject: any) =>
firebase.auth().onAuthStateChanged((user: any) =>
  resolve(user), (e: any) => reject(e)));
console.log(user1);
// sometimes does not display correctly when logging out
const user2 = await firebase.auth().authState.pipe(first()).toPromise();
console.log(user2);
// technically has a 3rd state of 'unknown' before login state is checked
const user3 = await firebase.auth().currentUser;
console.log(user3);
TL;DR:
expo sdk를 사용하여 여기에 오는 사람들을 위해.>=48또는 React Native를 업데이트한 후>=0.71화재 기지를 초기화해야 합니다.다음과 같은 사용자 지정 스토리지로 인증:
import { initializeAuth } from 'firebase/auth';
import { getApp } from 'firebase/app';
import { getReactNativePersistence } from 'firebase/auth/react-native';
import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage';
const storage = getReactNativePersistence(ReactNativeAsyncStorage)
const app = getApp();
initializeAuth(app, {
  persistence: storage,
});
설명:
AsyncStorage오래 전부터 사용되지 않아 V 0.71의 React Native에서 제거되었습니다.안타깝게도 Firebase 인증은 여전히 후드 아래 통합된 AsyncStorage에 의존하고 있습니다.
그 결과, 즉, (사용할 때에도)onAuthStateChanged위의 답변에서 설명한 바와 같이)getAuth().currentUser항상 그럴 것입니다.null앱을 닫았다가 다시 연 후.
이 문제는 https://github.com/firebase/firebase-js-sdk/pull/7128 에서 자세히 설명합니다.
  // 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*/}
이를 위한 최선의 방법은 약속을 사용하고 응답 후에만 라우터를 인스턴스화하는 것입니다. 이는 다음과 같습니다.
store.dispatch('userModule/checkAuth').then(() => {
  // whatever code you use to first initialise your router, add it in here, for example
  new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount('#app')
})
내부의다음과 같이 약속을 지킬 수 있는 곳이 바로 Auth Action입니다.
checkAuth ({ commit }) {
return new Promise((resolve, reject) => {
  firebase.auth().onAuthStateChanged(async (_user) => {
    if (_user) {
      commit('setUser', _user)
    } else {
      commit('setUser', null)
    }
    console.log('current user in checkAuth action:', _user)
    resolve(true)
  })
})
아롱크스 선더스에 대한 h/t - 저에게 이 해결책의 원천입니다.
사용자가 인증된 경우에만 특정 페이지에 액세스하고 인증되지 않은 경우 홈 페이지로 리디렉션하려면 다음 코드가 도움이 될 수 있습니다.
반응: 다음 코드로 구성 요소를 만듭니다.
import { onAuthStateChanged } from "@firebase/auth";
import { Route, Redirect } from "react-router-dom";
import { auth } from "../firebase/config";
import { useState, useEffect } from "react";
const GuardedRoute = ({ component, path }) => {
  const [authenticated, setAuthenticated] = useState(false);
  const [authCompleted, setAuthCompleted] = useState(false);
  useEffect(() => {
    onAuthStateChanged(auth, (user) => {
      if (user) {
        setAuthenticated(true);
      } else {
        setAuthenticated(false);
      }
      setAuthCompleted(true);
    });
  }, []);
  return authCompleted ? (
    authenticated ? (
      <Route path={path} component={component} />
    ) : (
      <Redirect to="/" />
    )
  ) : (
    ""
  );
};
export default GuardedRoute;
그리고 app.js에서는 다음을 사용합니다.
import RouterPage from "./pages/RouterPage";
<GuardedRoute path="/router-page" component={RouterPage} />
in Vue: 라우터 파일에서 다음을 사용합니다.
const guardSuccess = (to, from, next) => {
  let gUser = auth.currentUser
  if (gUser) {
    next()
  } else {
    next({ name: "Home" })
  }
}
액세스를 제한하여 추가할 페이지 경로:
 {
    path: "/router-page",
    name: "routerPage",
    component: () => import("../views/routerPage.vue"),
    beforeEnter: guardSuccess
  }
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();
    }
  });
먼저 사용자가 있는지 확인한 후 ID를 가져옵니다.
화력 기지auth().currentUser.uid
언급URL : https://stackoverflow.com/questions/37883981/cant-get-currentuser-on-load
'sourcecode' 카테고리의 다른 글
| 스레드화에서 join()의 용도는 무엇입니까? (0) | 2023.06.27 | 
|---|---|
| 열의 값이 고유한지 확인하기 위한 SQL 쿼리 (0) | 2023.06.27 | 
| OS X "El Capitan"에 보석을 설치할 수 없습니다. (0) | 2023.06.27 | 
| PL/SQL에서 출력을 새 줄로 인쇄하려면 어떻게 해야 합니까? (0) | 2023.06.27 | 
| Vuex getter 및 돌연변이 이해 (0) | 2023.06.27 |