Flutterfire: SignInWithEmailAndPassword unable to handle error when the email address is badly formatted

Created on 24 Aug 2020  ·  26Comments  ·  Source: FirebaseExtended/flutterfire

Here is my email sign in method in my FirebaseAuthService class:

  @override
  Future<UserCustom> signInWithEmail(
      String emailAddress, String password) async {
    try {
      UserCredential _signInWithEmailAndPasswordGoogle = await _auth
          .signInWithEmailAndPassword(email: emailAddress, password: password);
      if (_signInWithEmailAndPasswordGoogle.user != null) {
        return _userToUserModel(_signInWithEmailAndPasswordGoogle.user);
      } else {
        throw PlatformException(
            code: 'SIGN_IN_INTERRUPTED', message: 'Sin in interrupted');
      }
    } on PlatformException {
      print('Happened');
      rethrow;
    } catch(e){
      print(e.toString());
    }
  }

And here is where the exception should be handled:

  // creating the submit function
  Future<void> _submit(EmailSignInModelProviderPattern model) async {
    // if it is on sign in use sign in function ELSE use register function
    try {
      await model.submit();
      Navigator.pop(context);
    } on PlatformException catch (e) {
      CustomErrorPlatformException(
        title: 'Sign in failed',
        exception: e,
      ).show(context);
    } catch(e){
      print(e.toString());
    }
  }

And yet when I enter a badly formatted address the process is interrupted at message_codecs.dart file at the method dynamic decodeEnvelope(ByteData envelope) line 572 with error message See screenshot:

Exception has occurred.
PlatformException (PlatformException(firebase_auth, com.google.firebase.auth.FirebaseAuthInvalidCredentialsException: The email address is badly formatted., {code: invalid-email, additionalData: {}, message: The email address is badly formatted.}))

I couldn't figure out how to handle this exception, knowing that it never happened to me before upgrading to firebase_auth: ^0.18.0+1.

auth needs-repro

Most helpful comment

I am using vscode and experiencing the same problem with @dshundal94. Similarly, I was able to solve it by unchecking the 'Uncaught Exceptions' checkbox. Afterwards, it runs fine and the FirebaseAuthException was caught. So not sure if the problem is coming from vscode debugger or the firebase auth plugin.

All 26 comments

Hi @mehdiRezzagHebla Have you read: https://firebase.flutter.dev/docs/auth/error-handling

You need to catch the FirebaseAuthException:

try {
  await FirebaseAuth.instance.signInWithEmailAndPassword(
    email: "some invlaid emaill",
    password: "SuperSecretPassword!"
  );
} on FirebaseAuthException catch  (e) {
  if (e.code == 'invalid-email') {
    // Do something :D
  }
}

@Ehesp Didn't work.
Apparently the exception is not rethrown, it is thrown inside the auth module that's why I cannot handle it.
Here is the function that is throwing it:

@override
  dynamic decodeEnvelope(ByteData envelope) {
    // First byte is zero in success case, and non-zero otherwise.
    if (envelope.lengthInBytes == 0)
      throw const FormatException('Expected envelope, got nothing');
    final ReadBuffer buffer = ReadBuffer(envelope);
    if (buffer.getUint8() == 0)
      return messageCodec.readValue(buffer);
    final dynamic errorCode = messageCodec.readValue(buffer);
    final dynamic errorMessage = messageCodec.readValue(buffer);
    final dynamic errorDetails = messageCodec.readValue(buffer);
    if (errorCode is String && (errorMessage == null || errorMessage is String) && !buffer.hasRemaining)
      throw PlatformException(code: errorCode, message: errorMessage as String, details: errorDetails);
    else
      throw const FormatException('Invalid envelope');
  }
}

Which, then, redirects here:

Future<Map<K, V>> invokeMapMethod<K, V>(String method, [ dynamic arguments ]) async {
    final Map<dynamic, dynamic> result = await invokeMethod<Map<dynamic, dynamic>>(method, arguments);
    return result?.cast<K, V>();
  }

Can you create a reproduction repository please? I can't replicate this.

same thing happened to me.
I can login without any problem.
but it won't catch wrong email or password. It just throw the exception.
tried with try catch block, throw, onError method. doesn't work.
here is the repo:
https://github.com/dhanniex82/flutterFireAuthExample

Also, what platform is this?

Also, what platform is this?

Do yo mean the CustomErrorPlatformException ?
It is just a custom AlertDialog widget.

Also, what platform is this?

Do yo mean the CustomErrorPlatformException ?
It is just a custom AlertDialog widget.

@Ehesp probably referring to my post.
@mehdiRezzagHebla try this on your code:

try {
  await FirebaseAuth.instance.signInWithEmailAndPassword(
    email: "some invlaid emaill",
    password: "SuperSecretPassword!"
  ).then((UserCredential user) {
    if( user != null) {
    // do your thing here
}
});
} on FirebaseAuthException catch  (e) {
  print(e.code);
  print(e.message);
 // do some other thing
  }
}

Also, what platform is this?

Do yo mean the CustomErrorPlatformException ?
It is just a custom AlertDialog widget.

@Ehesp probably referring to my post.
@mehdiRezzagHebla try this on your code:

try {
  await FirebaseAuth.instance.signInWithEmailAndPassword(
    email: "some invlaid emaill",
    password: "SuperSecretPassword!"
  ).then((UserCredential user) {
    if( user != null) {
    // do your thing here
}
});
} on FirebaseAuthException catch  (e) {
  print(e.code);
  print(e.message);
 // do some other thing
  }
}

@dhanniex82 Already been suggested by @Ehesp , doesn't work.
Like I said, it is not a FirebaseAuthException it's a normal PlatformException that is thrown from message_codecs.dart file in the path C:\Program Files\ [flutter installation folder name] \packages\flutter\libsrc\services

the suggested code from @Ehesp on other post got

.then method
and I need to add user null check after that.

I managed to get it to work on Web platform though.

Hi @mehdiRezzagHebla,
As requested here, please provide a minimal reproducible code sample that shows the issue.
Thanks.

Hi @mehdiRezzagHebla,
As requested here, please provide a minimal reproducible code sample that shows the issue.
Thanks.

Sorry for the delay, I built a reproducible code but strangely it worked normally, I still fail to identify the difference between the original codebase and copy.
Anyway, I apologize for wasting your time guys, should I delete this issue?

@mehdiRezzagHebla Could you paste your reproducible code? I was getting the same issue as you before, where the message_codecs.dart file was being called when catching exceptions thrown by FirebaseAuth. It's probably something I'm doing wrong.

Thanks @mehdiRezzagHebla for confirming. Closing this as non-issue.

@dshundal94 here you go: here it is

@dshundal94 I would love to check out your auth_service class maybe it'll help up see what is wrong.

@mehdiRezzagHebla Here is the link to the test repository: https://github.com/dshundal94/testFlutterFireAuth
I get the unhandled exception when trying to login or even when the FirebaseAuthExceptions pop up.
image
image

I know I can probably not explicitly call setState() when trying to update the errorString probably with changeNotifier, but nonentheless, I get messages_codec.dart file getting accessed when trying to login. Most likely, I'm not handling the errors in the proper way.

@dshundal94 your code seems to be fine which makes me less comfortable since I don't know why this is happening and it could happen any time for some reason I still cannot figure out, I mean imagine this happening in a production ready app.
Please keep me updated if you find anything, I will do the same from my end.

@mehdiRezzagHebla Yeah, I've been tackling it for the past few days. I've just been trying to write out everything explicitly and see where I went wrong. Just a little frustrating since there seems to be hardly anything documented on why this would happen. I will update here if I find anything related to this.

@mehdiRezzagHebla I updated my repository. Before I was getting some sort of [ERROR:flutter/lib/ui/ui_dart_state(166).cc] Unhandled Exception error in my debug console, now at least I'm not getting that. Although when I run the app in debug mode, it is still accessing message_codecs.dart and throwing a PlatformException.

I changed two things mainly:
1) In my auth.dart file, I'm not error handling on my signIn function there.
2) I changed my signIn function from Future(String) to Future(void) and doing the error handling here with try and catch method.

I don't know if that helps, but I will continue to work at and update here if I find anything that will help.

@mehdiRezzagHebla I think it might be a problem with how I set up my IDE. After unchecking the BREAKPOINTS: Uncaught Exceptions box, the debugger does not break at the message_codecs.dart file. My suspicion is that the code executes before the catch clause can capture the FirebaseAuthException, but after stepping through the debugger, the catch clause will execute the code written in it without writing an error to the debug console. This seems to be a bug with dart debugging though, because we do catch the exception in our code, yet we still reach a breakpoint when debugging.

Would you know where to follow up on this?

I am using vscode and experiencing the same problem with @dshundal94. Similarly, I was able to solve it by unchecking the 'Uncaught Exceptions' checkbox. Afterwards, it runs fine and the FirebaseAuthException was caught. So not sure if the problem is coming from vscode debugger or the firebase auth plugin.

@dshundal94 sorry for the delayed response (timezone difference).
Thank you for spending the effort on tackling this, it seems intriguing, I think it is plausible that the IDE's debugger config is what's behind the problem, I am currently debugging an unrelated one in my project, and though I currently have no idea on how to follow up on this, I will get back to it in a few hours and keep you posted with my findings, cheers.

@dshundal94 just a side note on the latest dart v3.14.0 release does this have to anything to do with our issue?

#2699: When using “Debug my code” and an exception occurs with a call stack containing no user code, the top frame will now be selected to make it obvious that execution has paused.

@mehdiRezzagHebla Thanks for looking at this! I think it has to do when handling Futures. Looks like its native to how Dart looks at the debug stack trace as explained in this issue. I guess the current solution would either just step through the code when in debug mode, or uncheck the unhandled exception checkpoint (although this means that it won't catch the actual unhandled exceptions).

I think you can vote on this open issue here. Again, thanks for looking into this, appreciate the assist!!

@dshundal94 I was lurking around and I fould this description of PlatformException:
_Creates a PlatformException with the specified error code and optional message, and with the optional error details which must be a valid value for the MethodCodec involved in the interaction._
I am not sure but I think that it could have something to do with the formatting of PlatformException thrown by the _Firebase_Firestore_ package, I mean a normal PlatformException would be like:

PlatformException(
title: 'Some Title Here',
content: 'Description here',
message: 'Some message here')

But when you look at the PlatformException not being handled, it does not respect this syntax, take a look at the screenshot you shared above.
@darshankawar @Ehesp any thoughts on this?

@mehdiRezzagHebla Yeah, I saw that too and in my updated repository I don't get the [ERROR:flutter/lib/ui/ui_dart_state(166).cc] Unhandled Exception: Password associated with this password is wrong message in my debug console. I no longer throw PlatformExceptions when error handling.

I still however, do get the original PlatformException being thrown by the dart language:
image

In the flutterfire lib, a FirebaseAuthException is thrown anytime a error occurs when trying to sign in with email and password. Here is a link in the flutterfirelib that convert PlatformException to FirebaseAuthException.

Was this page helpful?
0 / 5 - 0 ratings