如何在Cloud Firestore用户注册时将当前用户UID存入用户集合
问题描述
我希望将Firebase Auth生成的唯一用户ID存入Cloud Firestore的users集合的userId字段。为此我编写了如下handleSubmit处理函数:
const handleSubmit = async (e) => { e.preventDefault(); const { email, password, fullname, username } = credentials try { await createUser({ email, password, fullname, username }) } catch (error) { console.log(error) setError(error.message) } }
该函数会调用AuthContext中的createUser函数,代码如下:
export const AuthContextProvider = ({ children }) => { const [user, setUser] = useState('') const [refUser, setRefUser] = useState('') console.log('checking on top ', user) // Sign Up function const createUser = async ({ email, password, fullname, username }) => { await createUserWithEmailAndPassword(auth, email, password) // creatinguser collection const date = new Date().toISOString(); const userRef = await addDoc(collection(db, "users"), { userId: '', username: username, email: email, name: fullname, followers: [], followings: [], posts: [], date: date }); await updateDoc(doc(db, "users", `${userRef?.id}`), { userId: "user?.uid" }); } useEffect(() => { const unsubscribe = onAuthStateChanged(auth, async (currentUser) => { setUser(currentUser); return () => { unsubscribe(); }; }); return ( <AuthContext.Provider value={{ createUser, user, refUser }}> {children} </AuthContext.Provider> )
请问如何实现仅在用户注册创建新账号时,通过updateDoc将用户UID存入userId字段?
解决方案
你的代码存在几处需要调整的细节,修正后即可实现需求:
- 直接获取注册用户的UID:
createUserWithEmailAndPassword方法会返回包含当前注册用户信息的凭证对象,无需依赖onAuthStateChanged回调,可直接从中提取uid。 - 修正变量引用错误:你当前写的
"user?.uid"是字符串字面量,并非变量引用,需要去掉引号并使用正确的用户UID变量。 - 确保仅注册时执行更新:
createUser函数本身就是注册专用逻辑,只要在该函数内完成UID写入,就只会在用户注册时触发。
修改后的createUser函数如下:
const createUser = async ({ email, password, fullname, username }) => { // 注册后直接获取用户凭证与UID const userCredential = await createUserWithEmailAndPassword(auth, email, password); const userId = userCredential.user.uid; const date = new Date().toISOString(); const userRef = await addDoc(collection(db, "users"), { userId: '', // 先留空,后续通过updateDoc更新 username: username, email: email, name: fullname, followers: [], followings: [], posts: [], date: date }); // 用真实UID更新userId字段 await updateDoc(userRef, { userId: userId }); // 可选:同步更新context中的用户状态 setUser(userCredential.user); }
更优写法(无需额外updateDoc请求)
实际上可以在创建Firestore文档时直接写入UID,省去一次额外的数据库请求,提升效率:
const createUser = async ({ email, password, fullname, username }) => { const userCredential = await createUserWithEmailAndPassword(auth, email, password); const userId = userCredential.user.uid; const date = new Date().toISOString(); // 创建文档时直接填入UID await addDoc(collection(db, "users"), { userId: userId, username: username, email: email, name: fullname, followers: [], followings: [], posts: [], date: date }); setUser(userCredential.user); }
另外,你的useEffect存在语法错误,清理函数需放在onAuthStateChanged回调外部,修正后:
useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (currentUser) => { setUser(currentUser); }); // 清理函数放在回调外部 return () => { unsubscribe(); }; }, []);
内容的提问来源于stack exchange,提问作者Sujjeee
相关产品推荐
相关产品推荐

