React JS中使用Firebase实现Google登录时如何检查用户是否已注册
实现方案
核心逻辑是基于Firebase Auth返回的用户唯一uid,查询Firestore中是否存在对应用户的账号记录,不存在时才执行写入操作。这里提供2种可行实现,更推荐第一种性能更高的方案:
方案1:使用uid作为文档ID(推荐)
直接将用户的uid设为Firestore Account集合的文档ID,无需遍历查询集合,读写效率更高,天然避免重复文档:
import { GoogleAuthProvider, signInWithPopup } from "firebase/auth"; import { db } from "你的firebase配置文件路径"; import { doc, getDoc, setDoc } from "firebase/firestore"; const ggProvider = new GoogleAuthProvider(); const handleGgLogin = async () => { const { user } = await signInWithPopup(auth, ggProvider); // 构造以用户uid为ID的文档引用 const userDocRef = doc(db, "Account", user.uid); // 查询该文档是否存在 const userDocSnap = await getDoc(userDocRef); const payload = { displayName: user.displayName, email: user.email, photoUrl: user.photoURL, uid: user.uid, }; if (!userDocSnap.exists()) { // 文档不存在,说明是首次登录,写入数据 await setDoc(userDocRef, payload); // 可在此处添加首次登录的额外逻辑,比如跳转新手引导页 } else { // 已注册过,跳过写入,直接走登录后逻辑即可 // 如果需要同步用户最新的谷歌账号信息(比如用户修改了头像),可以用带merge参数的setDoc更新字段,不会覆盖原有自定义数据 // await setDoc(userDocRef, payload, { merge: true }); } };
方案2:适配现有自动生成文档ID的逻辑
如果你不想修改现有集合的文档ID规则,仍然沿用addDoc自动生成ID的模式,可以先查询集合中匹配uid的文档再判断:
import { GoogleAuthProvider, signInWithPopup } from "firebase/auth"; import { db } from "你的firebase配置文件路径"; import { collection, query, where, getDocs, addDoc } from "firebase/firestore"; const ggProvider = new GoogleAuthProvider(); const handleGgLogin = async () => { const { user } = await signInWithPopup(auth, ggProvider); const collectionRef = collection(db, "Account"); // 构造查询条件:匹配当前登录用户的uid const q = query(collectionRef, where("uid", "==", user.uid)); const querySnapshot = await getDocs(q); const payload = { displayName: user.displayName, email: user.email, photoUrl: user.photoURL, uid: user.uid, }; if (querySnapshot.empty) { // 没有匹配的文档,说明是首次登录,写入数据 await addDoc(collectionRef, payload); } };
注意事项
- 使用方案2需要提前给Firestore的Account集合的
uid字段添加索引,否则查询会报错 - 方案1的读写性能远高于方案2,更推荐使用uid作为文档ID的集合设计
内容的提问来源于stack exchange,提问作者Kozfast
相关产品推荐
相关产品推荐

