ReactJS中基于Firebase自定义声明实现多角色导航UI展示
解决React + Firebase根据自定义声明切换导航栏的问题
嘿,你已经搞定了基础的登录状态判断,现在要区分管理员和普通用户来展示不同导航栏对吧?其实核心问题是Firebase的自定义声明不会自动包含在默认的auth对象里,我们需要手动获取用户的ID Token结果来拿到这些声明。下面一步步来实现:
步骤1:在Header组件中获取用户的自定义声明
因为你用的是函数式组件,我们可以用useState存储管理员状态,用useEffect在用户登录后异步获取ID Token:
修改你的Header.js代码:
import React, { useState, useEffect } from 'react'; import {Link} from 'react-router-dom'; import './Header.scss'; import PublicNavigation from '../PublicLinks/PublicLinks'; import AdminNavigation from '../AdminLinks/AdminLinks'; import UserNavigation from '../UserLinks/UserLinks'; import SignUpButton from '../SignUpButton/SignUpButton'; import { connect } from 'react-redux'; import LogOut from '../LogOut/LogOut'; // 导入你的Firebase实例(根据项目配置调整路径) import firebase from '../../firebase'; const Header = (props) => { const { auth } = props; const [isAdmin, setIsAdmin] = useState(false); const [isLoading, setIsLoading] = useState(true); // 处理加载状态 useEffect(() => { const checkAdminStatus = async () => { if (auth.uid) { try { const user = firebase.auth().currentUser; const idTokenResult = await user.getIdTokenResult(); // 从claims中读取admin自定义声明 setIsAdmin(idTokenResult.claims.admin || false); } catch (err) { console.error('获取管理员状态失败:', err); setIsAdmin(false); } } else { setIsAdmin(false); } setIsLoading(false); }; checkAdminStatus(); }, [auth.uid]); // 当用户登录/登出时重新检查状态 // 根据状态渲染对应导航栏 let nav; if (isLoading) { nav = <div>加载中...</div>; // 可替换为你的自定义加载组件 } else if (!auth.uid) { nav = <PublicNavigation/>; } else if (isAdmin) { nav = <AdminNavigation/>; } else { nav = <UserNavigation/>; } const button = auth.uid ? <LogOut/> : <SignUpButton/> return ( <div className = "Header"> <div className = "Logo"> <h1 className = "CompanyName"> Logo.</h1> </div> { button } <div className = "Navigation"> { nav } </div> </div> ) } const mapStateToProps = (state) => { return { auth: state.firebase.auth } } export default connect(mapStateToProps)(Header)
步骤2:关键逻辑解释
getIdTokenResult():这个方法会返回包含用户自定义声明的对象,我们从中取出claims.admin来判断用户是否为管理员。useEffect依赖auth.uid:当用户登录/登出时,auth.uid会发生变化,触发重新检查管理员状态的逻辑。- 加载状态处理:避免在获取声明的短暂间隙显示错误的导航栏,提升用户体验。
额外提示
- 如果你的项目使用
react-redux-firebase,也可以将管理员状态存储到Redux的profile或自定义state中,这样其他组件也能复用这个状态,无需重复调用getIdTokenResult()。 - 确保Firebase实例的导入路径与你的项目配置一致,比如部分项目会用
getAuth()从firebase/auth模块导入认证实例。
你的云函数addAdminRole已经正确实现了给用户添加admin自定义声明的功能,不需要修改。现在前端就能根据这个声明自动切换对应的导航栏啦~
内容的提问来源于stack exchange,提问作者Ryan Nisbet
相关产品推荐
相关产品推荐

