Firebase电子邮件验证无法正常运行

时间:2016-12-07 17:57:22

标签: android firebase firebase-authentication

我有什么

我在我的应用中使用 Firebase身份验证,用户可以使用电子邮件&密码即可。如果用户尚未验证其电子邮件,我会在验证其电子邮件之前停用某些功能。

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

问题

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

但如果他们退出并再次登录,isEmailVerified()会立即返回true。但是退出用户并再次登录是不好的。

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

6 个答案:

答案 0 :(得分:4)

嘿,我知道这是一个很老的话题,但是为我解决了这个问题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传递。

然后,您可以检查是否有任何更新的数据(即email已知)

答案 1 :(得分:1)

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

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

如果用户将应用程序从后台移到前台,我将其与AppState结合使用以运行重新加载。

答案 2 :(得分:1)

只需执行以下操作:

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

if(user.isEmailVerified())
{
     .....
      ...
}

答案 3 :(得分:0)

发送验证电子邮件后,您必须重新加载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());
        }
    }

就是这样!

答案 4 :(得分:0)

订阅用户身份验证状态可以解决此“错误”。

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'));
      }
    })
  }

答案 5 :(得分:0)

在我使用 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>
  );
};