3

I'm having the problem of sending the email verification link to a user while they are trying to register an account that was already created. I am coding with Flutter with Firebase as the back-end database.


final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;

   abstract class BaseAuth {
     Stream<String> get onAuthStateChanged;
     Future<String> currentUser();
     Future<String> resendVerifyEmail(BaseAuth auth, String email);
   } 

   class Auth implements BaseAuth {...}

   Future<String> currentUser() async {
      final FirebaseUser user = await _firebaseAuth.currentUser();
      print("Getting current user: " + user?.uid);
      return user?.uid;
   }

  Future<String> resendVerifyEmail(BaseAuth auth, String email) async {
    try {
      final FirebaseUser user = await _firebaseAuth.currentUser();
      user.sendEmailVerification();
      return user?.uid;
    } catch (e) {
      print("An Error occurred while sending verification link");
      print(e.toString());
      return null;
    }
   }

Inside the try block, when calling the method currentUser(), the code exits and returns to the method that calls resendVerifyEmail without finishing the try-catch block.

I am having difficulty getting the email verification to resend inside of the popup that call resendVerifyEmail.

Please let me know any alternative ways to send email verification from Firebase with Flutter or what to do with this.

  void _showVerifyEmailDialog(BuildContext context, String email) {
final BaseAuth auth = AuthProvider.of(context).auth;
showDialog(
  context: context,
  builder: (BuildContext context) {
    // return object of type Dialog
    return AlertDialog(
      title: new Text("Account Already Exists"),
      content: new Text("Please verify account in the link sent to email"),
      actions: <Widget>[
        new FlatButton(
          child: new Text("Resend verification email"),
          onPressed: () {
            Navigator.of(context).pop();
            auth.resendVerifyEmail();   <- Called from this line in login.dart

Why is the code exiting at the statement below without moving to next line of sending email?

final FirebaseUser user = await _firebaseAuth.currentUser();
William Humphries
  • 541
  • 1
  • 10
  • 21

1 Answers1

2

Seems like you are adding unnecessary items in your resendemail function. Here is how I implemented my own:

  Future<void> sendEmailVerification() async {
    final FirebaseUser user = await _firebaseAuth.currentUser();
    user.sendEmailVerification();
  }

Simply call it in after registering the user like this:

  await Auth().sendEmailVerification();
  await Auth().signOut();

Make sure the sign the user out so that they can't automatically login when they close and open your app. You should add checks as well in your login if the user has his email verified like this:

  Future<bool> isEmailVerified() async {
    final FirebaseUser user = await _firebaseAuth.currentUser();
    return user.isEmailVerified == null ? false : user.isEmailVerified;
  }

Just call it when you log the person in.

CoderUni
  • 5,474
  • 7
  • 26
  • 58
  • The issue I'm facing is the resendVerifyEmail is being called from a popup and the final FirebaseUser user = await _firebaseAuth.currentUser() immediately exits without sending the help link – William Humphries May 28 '20 at 22:22
  • 1
    Are you sure you are calling the code? Try adding a print statement at the first line of your try function to check that. I'm pretty sure you call it using Auth().resendVerifyEmail(); . If that doesn't work then place await auth.resendVerifyEmail(); above your navigator.pop() – CoderUni May 29 '20 at 03:24
  • You are right about placing the await in the onPressed: portion but I also see (when debugging) 'The method 'sendEmailVerification' was called on null.' after executing final FirebaseUser user = await _firebaseAuth.currentUser(); – William Humphries May 29 '20 at 03:32
  • 1
    _firebaseAuth.currentUser() is causing the problem. It is either the user is not logged in or that you are calling it incorrectly. – CoderUni May 29 '20 at 03:33
  • Thank you, I guess I am confused as to the functionality, if this user is trying to create an account but sees that it already exists while they are not logged in, how would the email get sent? – William Humphries May 29 '20 at 03:35
  • 1
    Whenever you create an account, you automatically get logged in. If there is an error, then it fails to login. You can show a message what happened. You have to make sure that the user is logged in before you can send the email. Check my answer out again so you would see how you can send the email. After sending the email, log them out so that they won't get through the login page when they restart your app. – CoderUni May 29 '20 at 03:40
  • I think I understand your answer and I understand more of the purpose of Account Verification, I was thinking of a user that opens the application for the first time, tries to create an account, and finds his email is already in use, is there no need to resend an email verification? I've successfully implemented sending the email on account creation, but not if the account already exists the feature of re-sending. – William Humphries May 29 '20 at 03:55
  • 1
    Not sure why its like that. You can Google it out. I've never thought about that. – CoderUni May 29 '20 at 03:57
  • I guess the user would just have to dig through their email to find the link that was originally sent, thanks for your help. – William Humphries May 29 '20 at 03:58