Firebase 电子邮件验证无法正常工作

Posted

技术标签:

【中文标题】Firebase 电子邮件验证无法正常工作【英文标题】:Firebase Email Verification Not Working Properly 【发布时间】:2017-04-22 19:04:13 【问题描述】:

我有什么

我在我的应用中使用 Firebase 身份验证,用户可以使用 电子邮件和密码 进行注册。如果用户没有验证他们的电子邮件,我会禁用一些功能,直到他们验证他们的电子邮件。

我还有一个按钮可以显式触发验证邮件,它只调用sendEmailVerification()。它运行良好,并且始终发送验证邮件。

问题

用户收到验证邮件,但当他/她验证并返回应用程序时,isEmailVerified() 始终为 false。所以我的应用程序仍然不允许用户使用所有功能,尽管他/她已经验证了他们的电子邮件。

但如果他们注销并再次登录,isEmailVerified() 会立即返回 true。但是注销用户然后重新登录不是很好吗?

这是 Firebase 中的错误吗?还是我做错了什么?

【问题讨论】:

我认为这是一个错误。希望 Firebaser 能回答。相关问题:***.com/a/40967256/4815718. 【参考方案1】:

嘿,我知道这是一个很老的线程,但是什么解决了我的问题FIRAuth.auth()?.currentUser.reload(completion: (error) in ... )

对于任何面临此问题的人。我正在使用最新的 Firebase 版本 10.0.1

更新

自从我发布我的解决方案后,Firebase 更改了它们的函数名称。

请注意,可以通过添加 stateDidChangeListener 来观察当前用户状态的所有变化。 Auth.auth()?.currentUser 不会立即更新,所以我所做的是将当前用户保存到我自己创建和维护的全局变量中。

Auth.auth().addStateDidChangeListener  (auth, user) in
 // ...

每当您调用Auth.auth()?.currentUser.reload() 时,一个刷新并准备好使用的用户对象将通过 stateDidChangeListener 传递。

然后您可以检查任何更新的数据(即 emailVerified)

【讨论】:

这对我有用。您是否在此之前注销并登录?还没试过。 @just_deko 我没有注销并登录。 这仍然不适合我。我必须让用户退出并重新登录。 @WalterMorawa 您是否正在检查来自 Auth.auth().addStateDidChangeListener (auth, user) in // ... 的用户对象? @WalterMorawa 我更新了我的回复。希望它有所帮助。也有助于阅读文档和指南firebase.google.com/docs/auth/ios/manage-users【参考方案2】:

这是我使用 react-native 解决这个问题的方法:

const user = firebase.auth().currentUser;
user.reload().then(() => 
  console.log(emailVerified: user.emailVerified)
)

如果用户将应用程序从后台带到前台,我将它与 AppState 结合起来运行重新加载。

【讨论】:

这是非常直接的解决方案。谢谢!【参考方案3】:

您必须在发送验证电子邮件后重新加载您的 Firebase 用户。

 mAuth.createUserWithEmailAndPassword(inputEmail.getText().toString(), inputPassword.getText().toString())
    .addOnCompleteListener(ResetPasswordActivity.this, task -> 
        user = mAuth.getCurrentUser();user.reload();
        if(mAuth.getCurrentUser().isEmailVerified())
            next();//intent to next activity
         else                
            mAuth.getCurrentUser().sendEmailVerification().addOnCompleteListener(task1 -> System.out.println("function"));
        
        if (task.isSuccessful()) 
            user = mAuth.getCurrentUser();
            System.out.println(user.isEmailVerified());
        
    

就是这样!

【讨论】:

"user.reload()",非常适合我!【参考方案4】:

这样做:

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
user.reload();

if(user.isEmailVerified())

     .....
      ...

【讨论】:

【参考方案5】:

订阅用户身份验证状态可能会解决这个“错误”。

constructor(
    public afAuth: AngularFireAuth,
    public router: Router
  ) 
    this.afAuth.authState.subscribe(user => 
      // here you verify if the user is emailVerified BEFORE storing him in local storage.
      // if you want to keep storing the user even
      // before email verification, you need to work out this logic
      if (user && user.emailVerified) 
        this.userData = user;
        localStorage.setItem('user', JSON.stringify(this.userData));
        JSON.parse(localStorage.getItem('user'));
       else 
        localStorage.setItem('user', null);
        JSON.parse(localStorage.getItem('user'));
      
    )
  

【讨论】:

【参考方案6】:

在我使用react-native-firebase 的情况下,订阅onAuthStateChanged 不会更新emailVerified。也没有订阅onUserChanged。唯一可行的方法是致电user.reload()

自动触发user.reload()

但是,我不希望用户按下另一个按钮来触发user.reload()。我希望它自动触发。这个问题已经在here 讨论过,似乎深度链接可以允许自动触发user.reload()。但我不喜欢深度链接。因此,这是我的解决方案。

注册用户后,转到电子邮件验证屏幕,告诉用户系统正在等待用户验证他/她的电子邮件(如下所示)。在这个屏幕上,我们通过setInterval 和一个虚拟状态变量每秒更新一次屏幕。每次更新时,都会自动调用user.reload()

const EmailVerScreen = (props: PropsT) => 
  const [user, setUser] = React.useState();
  const [dummy, setDummy] = React.useState(true);

  React.useEffect(() => 
    const subscriber = auth().onAuthStateChanged(curUser => setUser(curUser));
    return subscriber; // unsubscribe on unmount
  );

  React.useEffect(() => 
    const interval = setInterval(async () => 
      setDummy(!dummy);
      try 
        if (user) 
          await user.reload();
        
       catch (error) 
        console.log(error);
      
    , 1000);
    return () => clearInterval(interval);
  );

  return (
    <View>
      <Text>`Dummy is $dummy ? 'True' : 'False'`</Text>
      <Text>
        user
          ? user.emailVerified
            ? 'Verified'
            : 'Not verified'
          : 'User unavailable'
      </Text>
    </View>
  );
;

【讨论】:

以上是关于Firebase 电子邮件验证无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Flutter 和 Firebase 设置 Facebook 身份验证

添加 Firebase Unity 后,Google Play 游戏停止正常工作

Flutter Firebase auth facebook无法正常工作

与 Firebase 函数一起使用时,Nodemailer 无法正常工作

ReactJS 中的电子邮件验证无法正常工作 [重复]

Flutter 在尝试 Firebase 身份验证时无法捕获 PlatformException