[英]When the page is reloaded, firebase.auth.currentUser returns null
I'm trying to implement a firebase authentication to my web app with react.我正在尝试通过 React 对我的 web 应用程序实施 firebase 身份验证。
The log-in/out flow is like this.登录/退出流程是这样的。
The user who succeeded in sign-in at the SIGN-IN page, redirected to the HOME page.在 SIGN-IN 页面成功登录的用户被重定向到 HOME 页面。
When Non-authenticated user access to the HOME page, redirected to the SIGN-IN page非认证用户访问HOME页面时,重定向到SIGN-IN页面
It is confirmed that the user is redirected to the HOME page from SIGN-IN and the user who clicked "sign out" button at the HOME page is redirected to the SIGN-IN page.确认用户从 SIGN-IN 被重定向到 HOME 页面,并且在 HOME 页面单击“退出”按钮的用户被重定向到 SIGN-IN 页面。
However, the problem is when the authenticated user reloads the page at the HOME page, the user is redirected to the SIGN-IN page and then redirected to the HOME page.但是,问题是当经过身份验证的用户在 HOME 页面重新加载页面时,用户将被重定向到 SIGN-IN 页面,然后再被重定向到 HOME 页面。
I supposed than the authenticated user isn't redirected to the SIGN-IN page.我认为经过身份验证的用户不会被重定向到登录页面。
How can I fix this problem?我该如何解决这个问题?
My codes are following:我的代码如下:
import * as React from "react";
import { createContext, useContext } from "react";
import { firebase } from "../utils";
const FirebaseContext = createContext(firebase);
export const FirebaseProvider: React.FC = props => (
<FirebaseContext.Provider value={firebase}>
{props.children}
</FirebaseContext.Provider>
);
export const useFirebase = () => useContext(FirebaseContext);
import * as React from "react";
import { Route, Switch } from "react-router-dom";
import * as routes from "./constants/routes";
import { FirebaseProvider } from "./contexts/FirebaseContext";
import { Home } from "./pages/Home";
import { SignIn } from "./pages/SignIn";
const App: React.FC = () => {
return (
<FirebaseProvider>
<Switch>
<Route exact={true} path={routes.SIGN_IN} component={SignIn} />
<Route exact={true} path={routes.HOME} component={Home} />
</Switch>
</FirebaseProvider>
);
};
export default App;
import { useState, useEffect } from "react";
import { User } from "firebase";
export const useAuthUser = (firebase: any) => {
const [authUser, setAuthUser] = useState<User | null>(firebase.auth.currentUser);
useEffect(() => {
const unsubcribe = firebase.auth.onAuthStateChanged((user: User | null) => setAuthUser(user));
unsubcribe();
}, []);
return authUser;
};
import * as React from "react";
import { useHistory } from "react-router-dom";
import { useFirebase } from "../../contexts/FirebaseContext";
import { useAuthUser } from "../../Hooks/AuthUserHook";
import * as routes from "../../constants/routes";
import { SignInForm } from "./SignInForm";
export const SignIn: React.FC = () => {
const firebase = useFirebase();
const authUser = useAuthUser(firebase);
const history = useHistory();
if (authUser) {
history.push(routes.HOME);
}
return (
<div>
<h1>Sign in</h1>
<SignInForm />
</div>
);
};
import * as React from "react";
import { useHistory } from "react-router-dom";
import { useFirebase } from "../../contexts/FirebaseContext";
import { useAuthUser } from "../../Hooks/AuthUserHook";
import * as routes from "../../constants/routes";
export const Home: React.FC = () => {
const firebase = useFirebase();
const authUser = useAuthUser(firebase);
const history = useHistory();
if (!authUser) {
history.push(routes.SIGN_IN);
}
return (
<div>
<h2>Home Page</h2>
<p>The Home Page is accessible by every signed in user.</p>
</div>
);
};
Upon page load the Firebase SDK tries to restore the user's credentials from local storage.加载页面后,Firebase SDK 会尝试从本地存储恢复用户的凭据。 As part of this it checks with the server if the user's login session is still valid, and during that time the currentUser is null. Then once the login session is restored, it fires an
onAuthStateChanged
event with the new state. So you'll need to hook into that to update your state.作为其中的一部分,它会检查服务器是否用户的登录名 session 仍然有效,并且在此期间 currentUser 是 null。然后一旦登录名 session 恢复,它就会触发一个
onAuthStateChanged
事件,新的 state。所以你需要连接到它以更新您的 state。
The way I usually deal with this is to start on a "log in" screen and then redirect to the main screen when you get a valid user in your auth state change handler.我通常处理这个问题的方法是从“登录”屏幕开始,然后当您在 auth state 更改处理程序中获得有效用户时重定向到主屏幕。
One extra trick is to store your own flag in local storage when the user has authenticated before, and then read that when the page loads.一个额外的技巧是当用户之前已经过身份验证时将您自己的标志存储在本地存储中,然后在页面加载时读取它。 Since access to this local storage is synchronous, that means you can immediately show the main screen in cases where they've been signed in before.
由于对该本地存储的访问是同步的,这意味着您可以在他们之前登录过的情况下立即显示主屏幕。 Just keep in mind that your local flag may be wrong (as that's precisely why Firebase has to check with the server), so you should be able to then handle navigating back to the login screen.
请记住,您的本地标志可能是错误的(因为这正是 Firebase 必须与服务器核对的原因),因此您应该能够处理导航回登录屏幕。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.