React中对比当前用户uid与Firebase集合uid的代码问题排查
问题根因
匹配失败是3个核心逻辑错误导致的:
users是通过useState定义的数组,用来存储Admin集合下的所有文档数据,直接访问users.uid拿到的永远是undefined,自然不可能和当前用户uid相等。数组里的每一个元素(也就是你push的doc.data())才是单条管理员数据,uid字段存在单个元素对象上。- Firestore的
onSnapshot是异步监听逻辑,组件第一次渲染时users还是初始空数组,你在组件顶层直接写相等判断,会在数据还没从数据库拉回来的时候就执行,结果必然不对。 - 你当前拉取Admin集合全量数据再在前端比对的写法性能很差,集合数据量大的时候会浪费大量流量和加载时间。
修正方案
直接在Firestore查询阶段就按uid过滤,只查询当前登录用户是否在Admin集合中,不需要拉取全量数据,同时用独立状态存储校验结果,避免异步时序问题。
修正后的可运行代码:
import { useState, useEffect } from 'react'; import { auth, db } from './你的firebase配置引入路径'; import { collection, query, where, onSnapshot } from 'firebase/firestore'; function AuthCheck() { const [isAdmin, setIsAdmin] = useState(false); const [loading, setLoading] = useState(true); useEffect(() => { // 处理未登录边界场景,避免currentUser为null抛错 const currentUser = auth.currentUser; if (!currentUser) { setIsAdmin(false); setLoading(false); return; } const usersRef = collection(db, "Admin"); // 直接在查询层过滤匹配uid的文档,无需拉取全集合 const q = query(usersRef, where("uid", "==", currentUser.uid)); const unsub = onSnapshot(q, (querySnapshot) => { // 查询结果非空即代表当前用户在Admin集合内 setIsAdmin(!querySnapshot.empty); setLoading(false); }); return () => unsub(); }, []); if (loading) return <div>权限校验中...</div>; // 后续直接通过isAdmin状态做分支逻辑即可 return isAdmin ? <div>管理员权限,可访问管理功能</div> : <div>无访问权限</div>; }
特殊场景适配
如果你确实需要拉取全量Admin用户列表支撑其他业务逻辑,比对时需要遍历数组判断是否存在匹配项,且逻辑必须在users状态更新完成后执行:
// 等users状态更新完成后,用数组方法判断匹配项 const isAdmin = users.some(userItem => userItem.uid === auth.currentUser.uid);
内容的提问来源于stack exchange,提问作者Stevan94
相关产品推荐
相关产品推荐

