如何在 React 应用程序中处理 Firebase onAuthStateChanged 并相应地路由用户?
Posted
技术标签:
【中文标题】如何在 React 应用程序中处理 Firebase onAuthStateChanged 并相应地路由用户?【英文标题】:How to handle Firebase onAuthStateChanged in a React app and route users accordingly? 【发布时间】:2021-06-30 17:40:30 【问题描述】:我正在开发一个与 Firebase 集成的 React Web 应用程序,并且我正在尝试对我的用户进行身份验证。如果用户通过身份验证,我已经设置了我的路由以显示主页组件,否则显示登录页面。但是当我的应用程序第一次加载时,它会显示登录页面,它需要一两秒钟才能识别出用户实际上已经过身份验证,然后它会切换到主页。它看起来很乱,我猜我处理 onAuthStateChanged 的速度不够好或不够快。在我的 App 组件中,我订阅了一个 ReactObserver,它在身份验证状态发生变化时发出信号。我该怎么做才能避免这种奇怪的行为?
我的App.js
:
import BrowserRouter, Route from "react-router-dom";
import Home from "./Home";
import Login from "./Login";
import loggedIn, firebaseObserver from "../firebase";
import useEffect, useState from "react";
export default function App()
const [authenticated, setAuthenticated] = useState(loggedIn())
useEffect(() =>
firebaseObserver.subscribe('authStateChanged', data =>
setAuthenticated(data);
);
return () => firebaseObserver.unsubscribe('authStateChanged');
, []);
return <BrowserRouter>
<Route exact path="/" render=() => (authenticated ? <Home/> : <Login/>) />
</BrowserRouter>;
我的firebase.js
:
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/firestore";
import ReactObserver from 'react-event-observer';
const firebaseConfig =
apiKey: ...,
authDomain: ...,
projectId: ...,
storageBucket: ...,
messagingSenderId: ...,
appId: ...
;
firebase.initializeApp(firebaseConfig);
export const auth = firebase.auth();
export const firestore = firebase.firestore();
export const firebaseObserver = ReactObserver();
auth.onAuthStateChanged(function(user)
firebaseObserver.publish("authStateChanged", loggedIn())
);
export function loggedIn()
return !!auth.currentUser;
【问题讨论】:
【参考方案1】:它可能关心的人,添加一个简单的标志来说明何时实际加载身份验证解决了我的故障。我还添加了受保护的路线(受this article 启发,我想我现在可以继续我的项目了。
App.js
:
import BrowserRouter, Redirect, Route, Switch from "react-router-dom";
import Home from "./Home";
import Login from "./Login";
import PrivateRoute from "./PrivateRoute";
import loggedIn, firebaseObserver from "../firebase";
import useEffect, useState from "react";
export default function App()
const [authenticated, setAuthenticated] = useState(loggedIn());
const [isLoading, setIsLoading] = useState(true);
useEffect(() =>
firebaseObserver.subscribe('authStateChanged', data =>
setAuthenticated(data);
setIsLoading(false);
);
return () => firebaseObserver.unsubscribe('authStateChanged');
, []);
return isLoading ? <div/> :
<BrowserRouter>
<Switch>
<Route path="/" exact>
<Redirect to=authenticated ? "/home" : "/login" />
</Route>
<PrivateRoute path="/home" exact
component=Home
hasAccess=authenticated />
<PrivateRoute path="/login" exact
component=Login
hasAccess=!authenticated />
<Route path="*">
<Redirect to=authenticated ? "/home" : "/login" />
</Route>
</Switch>
</BrowserRouter>;
【讨论】:
以上是关于如何在 React 应用程序中处理 Firebase onAuthStateChanged 并相应地路由用户?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 firestoreConnect 指向 React-Redux-Firebase 中的嵌套集合?
如何在同构 React + React 路由器应用程序中处理发布请求
如何在 Rails / Webpacker / React 应用程序中处理图像?
如何将来自不同组件的 firebase auth 和 Cloud Firestore 用作单个 Firebase 应用程序