当前位置: 首页 > 知识库问答 >
问题:

如何在用户的电子邮件使用 Firebase/auth 和 react-native 验证用户的电子邮件后立即登录,而无需创建整个着陆页?

杨飞语
2023-03-14

注意:我已经看到了这个问题,但创建一个完整的登录页面来验证用户似乎有点过分。

我使用带有电子邮件和密码的 firebase/auth 向我的 react-native 应用程序添加了登录功能。到目前为止,这效果很好,我这样做没有任何问题。

然后,我继续向一个新用户发送验证电子邮件,并只允许他/她在电子邮件验证后使用该应用程序。同样,这里没有问题。

下一步是在验证电子邮件后立即登录用户。这就是我卡住的地方,因为 onAuthStateChanged 事件处理程序在用户按下电子邮件中的验证链接后不会更新。

有没有办法实时监听< code>emailVerified状态?我尝试使用< code>setInterval()进行轮询,但是效果并不好,因为在验证和登录之间有明显的延迟。我了解到一个可以传递给< code > sendEmailVerification 的continueLink,但是我不知道如何在react-native中实现它。

我使用的是 Expo,因此使用的是 Firebase SDK,而不是 Firebase react 原生包。

这是我用于注册的代码:

export const signUp = async (username: string, email: string, password: string) => {
    try {
        const auth = getAuth();
        if (email && password && username) {
            // sign up 
            const userCredential = await createUserWithEmailAndPassword(auth, email, password);
            // save username in firestore
            await setUserName(userCredential, username);
            // send Email Verification
            await sendEmailVerification(userCredential.user);
            return true;
        }
    } catch (error) {
        onError(error);
    }
};

这是我的onAuthStateChanged处理程序:

auth.onAuthStateChanged(authenticatedUser => {
            try {
                if (authenticatedUser?.emailVerified) {
                    setUser(authenticatedUser)
                } else {
                    setUser(null)
                }
            } catch (error) {
                console.log(error);
            }
        });

共有2个答案

巫马越彬
2023-03-14

使用下面的代码作为身份验证上下文。对于用户id,应使用“user.uid”

html lang-html prettyprint-override">import React, { useState, createContext } from "react";
import * as firebase from "firebase";

import { loginRequest } from "./authentication.service";

export const AuthenticationContext = createContext();

export const AuthenticationContextProvider = ({ children }) => {
const [isLoading, setIsLoading] = useState(false);
      const [user, setUser] = useState(null);
      const [error, setError] = useState(null);
      
       firebase.auth().onAuthStateChanged((usr) => {
        if (usr) {
          setUser(usr);
          setIsLoading(false);
        } else {
          setIsLoading(false);
        }
      });
      
      const onLogin = (email, password) => {
        setIsLoading(true);
        firebase.auth().signInWithEmailAndPassword(email, password)
          .then((u) => {
            setUser(u);
            setIsLoading(false);
          })
          .catch((e) => {
            setIsLoading(false);
            setError(e.toString());
          });
      };

      const onRegister = (email, password, repeatedPassword) => {
        setIsLoading(true);
        if (password !== repeatedPassword) {
          setError("Error: Passwords do not match");
          return;
        }
        firebase
          .auth()
          .createUserWithEmailAndPassword(email, password)
          .then((u) => {
            setUser(u);
            setIsLoading(false);
          })
          .catch((e) => {
            setIsLoading(false);
            setError(e.toString());
          });
      };

      const onLogout = () => {
        setUser(null);
        firebase.auth().signOut();
      };

      return (
        <AuthenticationContext.Provider
          value={{
            isAuthenticated: !!user,
            user,
            isLoading,
            error,
            onLogin,
            onRegister,
            onLogout,
          }}
        >
          {children}
        </AuthenticationContext.Provider>
      );
    };
乐正镜
2023-03-14

所以最后我还是回答了这个问题,但是我根据自己的需要做了一点修改。我会把我的步骤发布给所有做同样事情的人。

    < li >使用< code>firebase init创建一个简单的静态网站,并将其托管在firebase或其他地方(检查firebase控制台中的托管选项卡以开始) < li >按照本指南在网站上创建适当的处理程序 < li >将以下内容添加到您的< code>verificationHandler中以更新用户(不要忘记导入firestore)(我通过< code>continueURL发送用户Id,但可能有更好的方法)
// You can also use realtime database if you want
firebase.firestore().collection("users").doc(userId).set({
                            emailVerified: true
                        }, {merge: true}).then(() => {
                            message.textContent = "Your email has been verified.";
                        }).catch((error) => {
                            message.textContent = "The verification was invalid or is expired. Please try to send another verification email from within the app.";
                        });
const onUserDataChanged = (uid, callback) => {
   onSnapshot(doc(firestore, "users", uid), doc => callback(doc.data()));
}
// As an example
auth.onAuthStateChanged(authenticatedUser => {
             if (authenticatedUser && !authenticatedUser.emailVerified) {
                    unsubscribeFirestoreListener?.();
                    unsubscribeFirestoreListener = onUserDataChanged(authenticatedUser.uid, (data: any) => {
                        if (data?.emailVerified) {
                            setUser(authenticatedUser);
                            unsubscribeFirestoreListener?.();
                        }
                    });
             }
}
 类似资料:
  • 我正在创建一个将提供通知的Android应用程序。用户可以使用电话号码或电子邮件帐户选择加入。 我只需要验证用户输入的电子邮件,我不想创建Firebase帐户 Firebase 有一个 但这需要创建一个帐户。 换句话说,我只希望电子邮件验证与电话验证相同,Firebase只会向您发送代码或验证链接。 有没有一种方法可以在不创建帐户的情况下利用Firebase电子邮件验证?

  • 我希望身份验证组件允许用户登录输入用户名或电子邮件。在我的用户表中,两个字段-userName和userEmail都是唯一的。注册时,密码生成如下: sha1($username.$password); 问题是用户无法使用电子邮件登录。 应用程序控制器 用户控制器:登录功能如下: Auth。php:(我在这里对生成密码的方式做了一些更改,因为我正在使用cakephp会话自动登录到SMF论坛。) 我

  • 我正在提示我的应用程序用户提供电子邮件凭据。 在用户插入电子邮件并通过后,我想验证该帐户。 我正在使用javax。邮政有没有办法验证帐户?只确保凭据确实有效——否则我想显示一个无效用户并传递消息。 也许是某种表演方式: 并在不发送任何内容的情况下检查身份验证异常。

  • null 我需要重新验证用户,最好的方法是什么?在用户登录后,如何切换的状态? 谢谢

  • 我正在做一个React本地项目,使用Firebase。 我试图让用户在验证了他们的电子邮件地址后登录。我在注册时向用户发送一封电子邮件,用户单击验证链接以验证自己,然后应该能够登录。我当前的代码允许用户在验证后登录,但只有在我刷新了应用程序之后。我希望用户在验证后登录而无需刷新应用程序。我发现我可以在Firebase中使用getIdToken()来实现它。但不知何故,我似乎无法让它工作。有什么指示

  • 是否可以在创建 Firebase 用户之前发送验证电子邮件并验证电子邮件?在我的代码中,我只能在从 Firebase 调用使用电子邮件和密码创建用户方法后发送电子邮件验证。即使我没有验证电子邮件,我仍然可以在 Firebase 控制台中看到该电子邮件的条目。