当我使用 googleSignIn 时,用户在 Firestore 上重复

Posted

技术标签:

【中文标题】当我使用 googleSignIn 时,用户在 Firestore 上重复【英文标题】:Users duplicate on Firestore when I use googleSignIn 【发布时间】:2021-11-05 08:46:03 【问题描述】:

我有两种方法可以在 Firebase 中注册用户:通过电子邮件和通过 Google 登录。

我通过电子邮件执行用户注册如下:

signUp() 
  const auth = getAuth();
  const db = getFirestore();
  createUserWithEmailAndPassword(
    auth,
    this.createEmail,
    this.createPassword
  ).then(
    (userCredential) => 
      const user = userCredential.user;
      this.$router.push("/");
      addDoc(collection(db, "users"), 
        email: this.createEmail,
        name: this.createName,
      );
    ,
  );
,

换句话说,除了在 Firebase 身份验证中保存用户之外,我还将他们的姓名和电子邮件发送到 Firestore。这是我的第一个问题:

这是保存用户名和将来仍将添加到其中的数据的最有效方法吗?

最后,通过谷歌登录如下:

googleSignIn() 
  const auth = getAuth();
  const provider = new GoogleAuthProvider();
  signInWithPopup(auth, provider)
    .then((result) => 
      this.$router.push("/");
      addDoc(collection(db, "users"), 
        email: result.user.email,
        name: result.user.displayName,
      );
    )
,

这里出现了一个问题,因为如果用户在 Firebase 身份验证中多次登录,一切正常,但在 Firebase Firestore 中,每次使用 Google 登录时都会创建一个用户。

如何处理将用户存储在 Firestore 中的问题,尤其是来自 Google 登录的用户?

【问题讨论】:

【参考方案1】:

首先,我将router.push() 语句移动到addDoc() 下方,以便确认文档已添加,然后将用户重定向到其他页面。如果是 Google 登录,您可以通过获取附加信息访问 isNewUser 属性来检查用户是否是新用户。如果为真,则将文档添加到 Firestore,否则重定向到仪表板:

signInWithPopup(auth, provider)
  .then(async (result) => 
  
  // Check if user is new
  const isNewUser = getAdditionalUserInfo(result)

  if (isNewUser) 
    await addDoc(collection(db, "users"), 
      email: result.user.email,
      name: result.user.displayName,
    );
  
  this.$router.push("/");
)

最好将文档 ID 设置为用户的 Firebase 身份验证 UID,而不是使用生成另一个随机 ID 的addDoc(),以便更轻松地编写安全规则。尝试将代码重构为:

signInWithPopup(auth, provider)
  .then(async (result) => 
  
  // Check if user is new
  const isNewUser = getAdditionalUserInfo(result)
  const userId = result.user.uid

  if (isNewUser) 
    await setDoc(doc(db, "users", userId), 
      email: result.user.email,
      name: result.user.displayName,
    );
  
  this.$router.push("/");
)

【讨论】:

非常好的解决方案,但如果我将文档 ID 设置为用户的 Firebase Auth UID,它实际上看起来更有效。问题是:我该怎么做?我承认我在文档中查找过这个,但没有找到。 这绝对有效!我真的很感激。

以上是关于当我使用 googleSignIn 时,用户在 Firestore 上重复的主要内容,如果未能解决你的问题,请参考以下文章

GoogleSignIn.getLastSignedInAccount() 返回具有空字段的帐户

如何查看 GoogleSignIn 用户上传的图片或谷歌设置的默认图片

更改 GoogleSignIn pod 版本时使用未声明的类型“GIDSignInUIDelegate”

如何在 GoogleSignIn signInSilently 中捕获错误?

Android GoogleSignIn:多个帐户同时+失败时延迟登录

没有这样的模块 'GoogleSignIn' Xcode 9.3 和 Swift 4.1