8

When a user signs up in my app he gets a verification e-mail. The onAuthStateChanged-listener gets called when a user gets created using createUserWithEmailAndPassword but not after the email got verified.

I have a separate class which handles all authentications. The following method is to sign up user

Future<FirebaseUser> signUpUser(email, password) async {
final FirebaseUser user = await _auth.createUserWithEmailAndPassword(email: email, password: password);

assert (user != null);
assert (await user.getIdToken() != null);

return user;
}

This method is called in my StatefulWidget using this method

void _signUpUser() async {
try {
  await Auth().signUpUser(_email, _password)
    ..sendEmailVerification();
} catch (e) {
  print(e.toString());
}
}

And onAuthStateChanged is set up in the initState method of my StatefulWidget

  FirebaseAuth.instance.onAuthStateChanged.listen((user) {
  print("Auth State Changed!");
  if (user.isEmailVerified) {
    print("EMail verified!");
  }
  }
eli2003
  • 400
  • 5
  • 13
  • 1
    Is there something in the docs saying that the user will be automatically logged in when the email is verified? Also, maybe it could be the case that the authStatechanged would be called only once, after the registration, when the email will still be unverified, and the user would have to close and open the app. – George Feb 08 '19 at 12:05
  • 1
    https://stackoverflow.com/a/58039313/10511266 might help. – Hussnain Haidar Sep 21 '19 at 10:23

4 Answers4

3

onAuthStatechanged is triggered only in case of user Login or Logout & not on Email verification.

As Per Doc -

onAuthStatechanged Adds an observer for changes to the user's sign-in state.

The observer will be triggered in the following scenarios:

  • When auth().onAuthStateChanged() is first called. It will trigger with the initial Auth state. If the user is returning from an auth().signInWithRedirect() operation, the observer will wait for that operation to resolve before initially triggering.

  • When a new user signs.

  • When an already signed in user signs out.

anmol.majhail
  • 48,256
  • 14
  • 136
  • 105
  • 4
    But how is it then possible to get notified when the user verified his email? – eli2003 Feb 08 '19 at 13:44
  • 1
    You can force the ID token to be reloaded, which will get you the new value. I'm never sure if [`User.reload`](https://pub.dartlang.org/documentation/firebase_auth/latest/firebase_auth/FirebaseUser/reload.html) is enough, or if you need to call [`getIdToken(true)`](https://pub.dartlang.org/documentation/firebase_auth/latest/firebase_auth/FirebaseUser/getIdToken.html) before that. – Frank van Puffelen Feb 08 '19 at 14:48
2

You can simply do a firebase.auth().signOut after sending the email verification link. And when the user clicks on sign in again, it'll automatically fire onAuthStateChanged.

Sahil Tyagi
  • 147
  • 2
  • 5
1

At the moment I'm providing a button to 'complete email validation'. This calls User.reload - so this appears to be enough per @Frank van Puffelen's comment above. It's much less satisfactory than getting a status update event; I may implement a loop to check the status for a period after sending an email so that the app passes through automatically.

Richard K
  • 43
  • 7
0

Use the where Function:

final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;

  Stream<FirebaseUser> get onAuthStateChanged {
    return _firebaseAuth.onAuthStateChanged.where((user)=> user.isEmailVerified);
  }
mario francois
  • 1,291
  • 1
  • 9
  • 16