简体   繁体   English

firebase 应用程序中的身份验证流程问题 - 登录后,活动用户最初返回为 null

[英]Problems with authentication flow in firebase app - after login, active user initially returns as null

I have a React/Firebase app where I'm extracting the current active user from firebase, and passing it to the rest of the app as context.我有一个 React/Firebase 应用程序,我从 firebase 中提取当前活跃用户,并将其作为上下文传递给应用程序的 rest。
The user is set to context in the FirebaseContext.js file, and the problem is this: after I log in and console log the user object, it is logged as null .用户在FirebaseContext.js文件中设置为上下文,问题是这样的:在我登录并控制台登录用户 object 后,它被记录为null However, when I make a change in the FirebaseContext.js file and save it, the user object returns the correct object.但是,当我在FirebaseContext.js文件中进行更改并保存时,用户 object 返回正确的 object。
It's as if the code in FirebaseContext.js is not executed on login, and I'm not sure why.就好像FirebaseContext.js中的代码没有在登录时执行,我不确定为什么。 My understanding is that once a user logs in, their log in status is available to the entire app - or perhaps I've misunderstood.我的理解是,一旦用户登录,他们的登录状态对整个应用程序都是可用的——或者我可能误解了。 Suggestions on how to get login to work?关于如何让登录工作的建议?

The structure of the project is roughly as follows:项目结构大致如下:

src
|_components
|      |_Header.js
|
|_pages
|   | 
|   |_login.js
|
|_firebaseConfig.js
|
|_FirebaseContext.js

FirebaseContext.js FirebaseContext.js

import { useEffect,useState } from 'react'
import { auth } from "./firebaseConfig";
import { createContext } from "react";

export const FirebaseContext = createContext()

const user = auth.currentUser

console.log(`context  user: ${user}`)

const FirebaseContextProvider = (props) => {
        return(
            <FirebaseContext.Provider value = {{user}}>
                {props.children}
            </FirebaseContext.Provider>
        )
}

export default FirebaseContextProvider

Here's the login component Login.js这是登录组件Login.js

import { useState,useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth'

const Login = () => {

    const auth = getAuth()
    const user = auth.currentUser
    console.log(`this is user login ${user}`)

    const [{ email, password },setFormDetails] = useState({ email:'', password:''})
    const navigate = useNavigate()

    const handleChange = (e) => {
        e.preventDefault()
        const { name, value } = e.target
        setFormDetails(prevForm => ({
            ...prevForm,
            [name]: value
        }))
    }

const handleSubmit =   (e) => {
    e.preventDefault()
    const auth = getAuth()
    signInWithEmailAndPassword(auth,email,password)
    .then(() => {
        console.log('logged in')
        navigate('/')
    })
    .catch(err => {
        console.log(err)
    })
}

    useEffect(() => {
        document.title = 'Login - Wellyadvisor'
    },[])

    return(
        <div className = 'signup-container'>
            <p>Wellyadvisor</p>
            <form onSubmit = {handleSubmit} method = 'POST'>
                <input
                    type = 'text'
                    placeholder = 'Email'
                    aria-label = 'Enter your email'
                    name = 'email'
                    onChange = {handleChange}
                />
                <input
                    type = 'password'
                    placeholder = 'Password'
                    aria-label = 'Enter your password'
                    name = 'password'
                    onChange = {handleChange}
                />
                <button type ='submit'>
                    Login
                </button>
            </form>
        </div>
    )
}

export default Login

When you run:当你运行时:

const user = auth.currentUser

That is a synchronous calls that simply returns the value of the property when that line of code executes.这是一个同步调用,当该行代码执行时,它只返回属性的值。

But the user's authentication state is an interactive process with many moving parts, such as your call to signInWithEmailAndPassword , but also the SDK itself, which automatically refreshes the sign-in state every hour, and signs the user out when for example you've disabled their account.但是用户的身份验证 state 是一个包含许多活动部分的交互过程,例如您对signInWithEmailAndPassword的调用,还有 SDK 本身,它每小时自动刷新登录 state,并在您禁用时将用户注销他们的帐户。

For this reason you should use an auth state listener, as shown in the first code sample in the documentation on getting the current user :出于这个原因,您应该使用 auth state 侦听器,如有关获取当前用户的文档中的第一个代码示例所示:

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    // User is signed in, see docs for a list of available properties
    // https://firebase.google.com/docs/reference/js/firebase.User
    var uid = user.uid;
    // ...
  } else {
    // User is signed out
    // ...
  }
});

If you use this approach, and store the user in the state, you can simply refresh the state when the login state changes, which will then reactively update the UI.如果您使用这种方法,并将用户存储在 state 中,则当登录 state 发生变化时,您可以简单地刷新 state,这将反应性地更新 UI。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM