Unable to catch exception in Flutter thrown during the Firebase Email Sign Up process

Viewed 849

I'm trying to catch the exceptions thrown by Firebase during the email sign-up process in Flutter. But the exception isn't getting caught. I'm not sure what exactly I'm doing wrong.

  Future<dynamic> signUpWithEmail({
    required BuildContext context,
    required String userName,
    required String userEmail,
    required String userPassword,
  }) async {
    User? firebaseUser;
    try {
      authInstance
          .createUserWithEmailAndPassword(
        email: userEmail,
        password: userPassword,
      )
          .then((value) async {
        if (value.user != null) {
          await value.user!.updateDisplayName(userName);
          await value.user!.reload();
          firestoreInstance.collection("users").doc(value.user!.uid).set({
            "name": userName,
            "photo": null,
            "emailAddress": value.user!.email,
            "signUpMethod": "email",
            "accountCreatedOn": Timestamp.now(),
            "receiveOffers": true,
            "isAdmin": false,
            "isAuth": false,
            "isSubscribed": false,
          }).then((value) async {
            await authInstance
                .signInWithEmailAndPassword(
              email: userEmail,
              password: userPassword,
            )
                .then((value) {
              firebaseUser = authInstance.currentUser;
              Navigator.of(context).push(ScaledAnimationPageRoute(HomePage()));
            });
          });
        }
      });
    } on FirebaseAuthException catch (e) {
      if (e.code == 'weak-password') {
        print('The password provided is too weak.');
      } else if (e.code == 'email-already-in-use') {
        print('An account already exists for that email address you are trying to sign up.');
      }
    } on FirebaseException catch (e) {
      print("Firebase Exception thrown on Sign Up page");
      print(e.message);
    } on PlatformException catch (e) {
      print("Platform Exception thrown on Sign Up page");
      print(e.message);
    } catch (e) {
      print("Exception thrown on Sign Up page");
      print(e);
    }
    return firebaseUser;
  }

I'm seeing the following error in the console.


E/flutter (19359): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: [firebase_auth/email-already-in-use] The email address is already in use by another account.
E/flutter (19359): #0      MethodChannelFirebaseAuth.createUserWithEmailAndPassword (package:firebase_auth_platform_interface/src/method_channel/method_channel_firebase_auth.dart:270:7)
E/flutter (19359): <asynchronous suspension>
E/flutter (19359): #1      FirebaseAuth.createUserWithEmailAndPassword (package:firebase_auth/src/firebase_auth.dart:211:7)
E/flutter (19359): <asynchronous suspension>
E/flutter (19359): 
E/libEGL  (19359): call to OpenGL ES API with no current context (logged once per thread)

Could anyone please help me in getting this fixed. Thanks for your help in advance.

2 Answers

You need to update the code to use async-await instead of .then() since you're using a try-catch.

When you use .then() on a Future, it's errors are caught by the .catchError() callback. And since you don't have a .catchError(), the error is registered as uncaught.

Your updated code will be:

Future<dynamic> signUpWithEmail({
  required BuildContext context,
  required String userName,
  required String userEmail,
  required String userPassword,
}) async {
  User? firebaseUser;
  try {
    final UserCredential value =
        await authInstance.createUserWithEmailAndPassword(
      email: userEmail,
      password: userPassword,
    );

    if (value.user != null) {
      await value.user!.updateDisplayName(userName);
      await value.user!.reload();

      await firestoreInstance.collection("users").doc(value.user!.uid).set({
        "name": userName,
        "photo": null,
        "emailAddress": value.user!.email,
        "signUpMethod": "email",
        "accountCreatedOn": Timestamp.now(),
        "receiveOffers": true,
        "isAdmin": false,
        "isAuth": false,
        "isSubscribed": false,
      });

      await authInstance.signInWithEmailAndPassword(
        email: userEmail,
        password: userPassword,
      );

      firebaseUser = authInstance.currentUser;
      Navigator.of(context).push(ScaledAnimationPageRoute(HomePage()));
    }
  } on FirebaseAuthException catch (e) {
    if (e.code == 'weak-password') {
      print('The password provided is too weak.');
    } else if (e.code == 'email-already-in-use') {
      print(
          'An account already exists for that email address you are trying to sign up.');
    }
  } on FirebaseException catch (e) {
    print("Firebase Exception thrown on Sign Up page");
    print(e.message);
  } on PlatformException catch (e) {
    print("Platform Exception thrown on Sign Up page");
    print(e.message);
  } catch (e) {
    print("Exception thrown on Sign Up page");
    print(e);
  }
  return firebaseUser;
}

I would suggest using the .contains method to check for the type of the error in the response from the server in the catch segment eg

if(e.code.contains('WEAK_PASSWORD')){
   print('This password is too weak')
 }
Related