Firebase自定义用户名设置问题:登录后校验逻辑及代码排查
问题描述
用户首次通过Google Auth登录时,UsersData集合中对应用户user.uid的文档会被自动设置一个值为空的username字段。需求逻辑如下:
- 校验用户名长度是否大于3(最小长度要求)
- 若已设置符合长度要求的用户名,不做任何操作
- 否则弹出模态框让用户设置用户名
当前登录后的校验代码无法正常工作,需排查问题并修正。
校验代码的问题分析与修正
原代码的核心问题
- 逻辑矛盾:第一个判断条件
!docSnap.exists() && docSnap.data().username.length > 3完全不合理——文档不存在时根本无法调用docSnap.data(),会直接抛出错误 - 逻辑覆盖不全:未处理文档存在但
username为空或长度≤3的情况 - 缺乏容错:未考虑
username字段不存在的极端场景(尽管需求说明首次登录会设置空值,但代码需做兼容)
修正后的校验代码
const [user] = useAuthState(auth); // 用状态控制模态框显示(根据你的Recoil或本地状态方案调整) const [showSetUsernameModal, setShowSetUsernameModal] = useState(false); const CheckUsername = async () => { if (!user) return; const docRef = doc(db, "UsersData", user.uid); const docSnap = await getDoc(docRef); if (docSnap.exists()) { const userData = docSnap.data(); // 检查用户名是否存在且长度符合要求 const hasValidUsername = userData.username && userData.username.length > 3; // 不符合要求则弹出模态框 setShowSetUsernameModal(!hasValidUsername); } else { // 极端情况:文档不存在,直接弹出模态框做兼容 setShowSetUsernameModal(true); } }; useEffect(() => { if (user) { CheckUsername(); } }, [user]);
设置用户名模态框的问题分析与修正
原代码的核心问题
- 查询方法错误:使用
getDoc()查询集合级别的查询对象——getDoc()仅用于单文档查询,集合查询必须用getDocs() - 缺乏输入校验:未检查输入的用户名长度是否满足≥3的要求
修正后的模态框代码
const [user] = useAuthState(auth); const [usernameValue, setUsernameValue] = useState(""); const SetUsername = async () => { try { // 先校验输入长度 if (usernameValue.length <= 3) { console.log("用户名长度必须大于3"); return; } const UserRef = collection(db, "UsersData"); const UsernameQuery = query(UserRef, where("username", "==", usernameValue)); // 集合查询使用getDocs() const querySnapshot = await getDocs(UsernameQuery); // 检查用户名是否已存在 if (querySnapshot.empty) { await updateDoc(doc(db, "UsersData", user.uid), { username: usernameValue, }); // 设置成功后关闭模态框(根据你的状态管理方案调整) // 示例:setShowSetUsernameModal(false); } else { console.log("用户名已存在,请更换"); } } catch (error) { console.error("设置用户名出错:", error); } }; return ( <div> <input type="text" onChange={(e) => setUsernameValue(e.target.value)} placeholder="请输入用户名(长度大于3)" /> <button onClick={SetUsername}>设置用户名</button> </div> );
内容的提问来源于stack exchange,提问作者Mintee
相关产品推荐
相关产品推荐

