Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Handle Firebase Auth exceptions on flutter

Please does anyone know how to catch firebase Auth exceptions on flutter and display them?

Note: I am not interested in the console (catcherror((e) print(e))

I need something that is more effective, e.g " user doesn't exist" So that I can then pass it to a string and display it.

Been dealing with this for months.

Thanks in advance.

I have tried replacing print(e) with // errorMessage=e.toString(); and then passing it to a function, all efforts have been futile.

    FirebaseAuth.instance
              .signInWithEmailAndPassword(email: emailController.text, password: passwordController.text)
              .then((FirebaseUser user) {
                _isInAsyncCall=false;
            Navigator.of(context).pushReplacementNamed("/TheNextPage");

          }).catchError((e) {
           // errorMessage=e.toString();
            print(e);
            _showDialog(errorMessage);

            //exceptionNotice();
            //print(e);

I want to be able to extract the exception message and pass the exception message to a dialog that I can then display to the user.

like image 299
rizu Avatar asked May 13 '19 13:05

rizu


People also ask

How do you catch errors in Firebase authentication?

Usefirebase. auth. Error. code to get the specific error code.


3 Answers

If you are using firebase_auth: ^0.18.0, error codes have changed! Check the next answer.

I just coded myself a way to do this without Platform dependent Code:

This is possible since .signInWithEmailAndPassword correctly throws Errors with defined codes, that we can grab to identify the error and handle things in the way the should be handled.

The following example creates a new Future.error, if any error happens, and a Bloc is then configured to shovel that data through to the Widget.

Future<String> signIn(String email, String password) async {
  FirebaseUser user;
  String errorMessage;
  
  try {
    AuthResult result = await _firebaseAuth.signInWithEmailAndPassword(email: email, password: password);
    user = result.user;
  } catch (error) {
    switch (error.code) {
      case "ERROR_INVALID_EMAIL":
        errorMessage = "Your email address appears to be malformed.";
        break;
      case "ERROR_WRONG_PASSWORD":
        errorMessage = "Your password is wrong.";
        break;
      case "ERROR_USER_NOT_FOUND":
        errorMessage = "User with this email doesn't exist.";
        break;
      case "ERROR_USER_DISABLED":
        errorMessage = "User with this email has been disabled.";
        break;
      case "ERROR_TOO_MANY_REQUESTS":
        errorMessage = "Too many requests. Try again later.";
        break;
      case "ERROR_OPERATION_NOT_ALLOWED":
        errorMessage = "Signing in with Email and Password is not enabled.";
        break;
      default:
        errorMessage = "An undefined Error happened.";
    }
  }

  if (errorMessage != null) {
    return Future.error(errorMessage);
  }

  return user.uid;
}
like image 109
TheRealHypo Avatar answered Oct 31 '22 02:10

TheRealHypo


NEW ANSWER (18/09/2020)

If you are using firebase_auth: ^0.18.0, error codes have changed!

For instance: ERROR_USER_NOT_FOUND is now user-not-found

I could not find any documentation about that, so I went into the source code and read comments for every error codes. (firebase_auth.dart)

I don't use all error codes in my app (e.g verification, password reset...) but you will find the most common ones in this code snippet:

(It handles old and new error codes)

String getMessageFromErrorCode() {
    switch (this.errorCode) {
      case "ERROR_EMAIL_ALREADY_IN_USE":
      case "account-exists-with-different-credential":
      case "email-already-in-use":
        return "Email already used. Go to login page.";
        break;
      case "ERROR_WRONG_PASSWORD":
      case "wrong-password":
        return "Wrong email/password combination.";
        break;
      case "ERROR_USER_NOT_FOUND":
      case "user-not-found":
        return "No user found with this email.";
        break;
      case "ERROR_USER_DISABLED":
      case "user-disabled":
        return "User disabled.";
        break;
      case "ERROR_TOO_MANY_REQUESTS":
      case "operation-not-allowed":
        return "Too many requests to log into this account.";
        break;
      case "ERROR_OPERATION_NOT_ALLOWED":
      case "operation-not-allowed":
        return "Server error, please try again later.";
        break;
      case "ERROR_INVALID_EMAIL":
      case "invalid-email":
        return "Email address is invalid.";
        break;
      default:
        return "Login failed. Please try again.";
        break;
    }
  }
like image 37
Corentin Houdayer Avatar answered Oct 31 '22 03:10

Corentin Houdayer


(21/02/20) EDIT: This answer is old and the other answers contains cross platform solutions so you should look at theirs first and treat this as a fallback solution.

The firebase auth plugin doesn't really have a proper cross-platform error code system yet so you have to handle errors for android and ios independently.

I'm currently using the temporary fix from this github issue: #20223

Do note since its a temp fix, don't expect it to be fully reliable as a permanent solution.

enum authProblems { UserNotFound, PasswordNotValid, NetworkError }

try {
  FirebaseUser user = await FirebaseAuth.instance.signInWithEmailAndPassword(
      email: email,
      password: password,
  );
} catch (e) {
  authProblems errorType;
  if (Platform.isAndroid) {
    switch (e.message) {
      case 'There is no user record corresponding to this identifier. The user may have been deleted.':
        errorType = authProblems.UserNotFound;
        break;
      case 'The password is invalid or the user does not have a password.':
        errorType = authProblems.PasswordNotValid;
        break;
      case 'A network error (such as timeout, interrupted connection or unreachable host) has occurred.':
        errorType = authProblems.NetworkError;
        break;
      // ...
      default:
        print('Case ${e.message} is not yet implemented');
    }
  } else if (Platform.isIOS) {
    switch (e.code) {
      case 'Error 17011':
        errorType = authProblems.UserNotFound;
        break;
      case 'Error 17009':
        errorType = authProblems.PasswordNotValid;
        break;
      case 'Error 17020':
        errorType = authProblems.NetworkError;
        break;
      // ...
      default:
        print('Case ${e.message} is not yet implemented');
    }
  }
  print('The error is $errorType');
}
like image 45
Swift Avatar answered Oct 31 '22 02:10

Swift