firebase,linkWithCredential 将新的身份验证提供程序添加到帐户

问题描述 投票:0回答:1

我正在使用 Firebase 身份验证和 Firestore 在 React 应用程序中构建注册组件。我想实现以下功能:

如果用户尝试向 Google 注册并且他们已存在于 Firestore 中,则应将他们重定向到主页。 如果它们不存在,我想在 Firestore 中创建一个新文档。 如果用户已经拥有一个包含电子邮件/密码的帐户,我想将 Google 帐户链接为附加提供商。

我遇到一个问题,当我测试它时,如果用户有电子邮件/密码提供商,它将删除它并仅添加 Google 提供商。

const handleEmailPasswordRegistration = async (e) => {
    e.preventDefault();
    setEmailloading(true);
    setMessage({ type: "", text: "" });

    try {
      const userCredential = await createUserWithEmailAndPassword(
        auth,
        email,
        password
      );
      const user = userCredential.user;

      await setDoc(doc(db, "users", user.uid), {
        firstName,
        lastName,
        email: user.email,
        createdAt: new Date(),
      });

      setMessage({ type: "success", text: "Registration successful!" });
      navigate("/");
    } catch (error) {
      console.error(error);
      setMessage({ type: "error", text: error.message });
    } finally {
      setEmailloading(false);
    }
  };

  const handleGoogleRegistration = async () => {
    setGoogleloading(true);
    setMessage({ type: "", text: "" });

    try {
      const result = await signInWithPopup(auth, googleProvider);
      const user = result.user;

      const userRef = doc(db, "users", user.uid);
      const docSnap = await getDoc(userRef);

      if (docSnap.exists()) {
        if (
          user.providerData.some(
            (provider) => provider.providerId === "google.com"
          )
        ) {
          setMessage({
            type: "success",
            text: "You are already registered with Google!",
          });
        } else {
          const credential = GoogleAuthProvider.credentialFromResult(result);
          await linkWithCredential(user, credential);
          setMessage({
            type: "success",
            text: "Google account successfully linked to your existing account!",
          });
        }
      } else {
        await setDoc(doc(db, "users", user.uid), {
          firstName: user.displayName?.split(" ")[0] || "",
          lastName: user.displayName?.split(" ")[1] || "",
          email: user.email,
          createdAt: new Date(),
        });

        setMessage({
          type: "success",
          text: "Registration successful with Google!",
        });
      }

      navigate("/");
    } catch (error) {
      console.error(error);
      setMessage({ type: "error", text: error.message });
    } finally {
      setGoogleloading(false);
    }
  };

我正在努力解决如何正确检查 Firestore 中的用户是否存在并链接其他(谷歌)身份验证提供商而不覆盖现有身份验证提供商(电子邮件/密码)。

我使用了

linkWithCredentials
以及
linkWithPopUp
但它仍然会删除并添加 google 提供商作为身份验证提供商。

reactjs firebase google-cloud-firestore firebase-authentication
1个回答
0
投票

它不会覆盖用户,而是覆盖用户身份验证提供程序。如果用户使用电子邮件/密码注册,然后注销并尝试使用其 Google 帐户登录,它将删除电子邮件和密码并使用 Google 身份验证作为提供商。

您所遇到的是预期行为,因为当用户使用电子邮件和密码登录并随后使用 Google 提供商登录时,Firebase 身份验证中的数据始终会被覆盖。这意味着 Google 凭据仍为默认凭据,之前选择的电子邮件和密码将不再用于对用户进行身份验证。发生这种情况的原因很明显,Google 帐户是比任何其他提供商(包括电子邮件和密码)更值得信赖的来源。

如果您想同时使用两种身份验证类型,我建议您根据电子邮件地址将这 2 个帐户链接到一个帐户中

© www.soinside.com 2019 - 2024. All rights reserved.