I'm working on a project that requires Firebase Auth.
When I try to catch an error when an email that's already in use, I get the error in the console, but the catch statement never gets executed. I also (always) get a weird null value error, but that doesn't seem to break anything. The second error message is what I am focusing on. Here are the error messages:
Error: Unexpected null value.
at Object.throw_ [as throw] (http://localhost:33663/dart_sdk.js:5067:11)
at Object.nullCheck (http://localhost:33663/dart_sdk.js:5394:30)
at http://localhost:33663/packages/fischerliste/message_list.dart.lib.js:983:62
at _RootZone.runUnary (http://localhost:33663/dart_sdk.js:40441:59)
at _FutureListener.then.handleValue (http://localhost:33663/dart_sdk.js:35363:29)
at handleValueCallback (http://localhost:33663/dart_sdk.js:35931:49)
at Function._propagateToListeners (http://localhost:33663/dart_sdk.js:35969:17)
at _Future.new.[_completeWithValue] (http://localhost:33663/dart_sdk.js:35817:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:33663/dart_sdk.js:35838:35)
at Object._microtaskLoop (http://localhost:33663/dart_sdk.js:40708:13)
at _startMicrotaskLoop (http://localhost:33663/dart_sdk.js:40714:13)
at http://localhost:33663/dart_sdk.js:36191:9
Error: [firebase_auth/email-already-in-use] The email address is already in use by another account.
at Object.throw_ [as throw] (http://localhost:33663/dart_sdk.js:5067:11)
at firebase_auth_web.FirebaseAuthWeb.new.createUserWithEmailAndPassword (http://localhost:33663/packages/firebase_auth_web/firebase_auth_web.dart.lib.js:156:23)
at createUserWithEmailAndPassword.throw (<anonymous>)
at http://localhost:33663/dart_sdk.js:40576:38
at _RootZone.runBinary (http://localhost:33663/dart_sdk.js:40445:59)
at _FutureListener.thenAwait.handleError (http://localhost:33663/dart_sdk.js:35374:33)
at handleError (http://localhost:33663/dart_sdk.js:35947:51)
at Function._propagateToListeners (http://localhost:33663/dart_sdk.js:35973:17)
at _Future.new.[_completeError] (http://localhost:33663/dart_sdk.js:35823:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:33663/dart_sdk.js:35859:31)
at Object._microtaskLoop (http://localhost:33663/dart_sdk.js:40708:13)
at _startMicrotaskLoop (http://localhost:33663/dart_sdk.js:40714:13)
at http://localhost:33663/dart_sdk.js:36191:9
Here is my code:
(you can find everything at https://github.com/fischerliste/fischerliste/tree/master/lib)
import 'package:flutter/scheduler.dart';
import 'data/message_dao.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
class MessageListState extends State<MessageList> {
MessageListState();
FirebaseApp app = Firebase.app();
String? uid;
SharedPreferences? prefs;
FirebaseAuth auth = FirebaseAuth.instanceFor(app: Firebase.app());
UserCredential? credential;
@override
void initState() {
SharedPreferences.getInstance().then((SharedPreferences? value) {
prefs = value;
uid = prefs!.getString('UID');
});
super.initState();
}
@override
Widget build(BuildContext context) {
if (uid == null) {
SchedulerBinding.instance?.addPostFrameCallback((_) {
Navigator.of(context)
.push(showSigninPopup(context, auth))
.then((value) {
credential = value;
prefs!.setString('UID', uid!);
return uid = "1234test";
});
});
}
return Scaffold();
//layout code here removed to make it shorter, but in case you want to
//see it, github link can be found above.
}
}
DialogRoute showSigninPopup(BuildContext buildcontext, FirebaseAuth auth) {
UserCredential? credential;
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
bool createUser() {
try {
auth.createUserWithEmailAndPassword(
email: emailController.text, password: passwordController.text)
.then((UserCredential? value) {
credential = value;
});
} catch (e) {
print('==================');
print('This never gets executed');
print(e);
}
return true;
}
bool checkSignin() {
try {
auth.signInWithEmailAndPassword(
email: emailController.text, password: passwordController.text)
.then((value) {
print(value);
});
} catch (exception) {
print(exception);
}
return true;
}
return DialogRoute(
barrierDismissible: false,
builder: (context) {
return AlertDialog(
title: const Text("Bitte anmelden!"),
content: Column(
children: [
TextField(
controller: emailController,
decoration: const InputDecoration(labelText: 'Email'),
),
TextField(
controller: passwordController,
decoration: const InputDecoration(labelText: 'Passwort'),
obscureText: true,
),
],
mainAxisSize: MainAxisSize.min,
),
actions: <Widget>[
TextButton(
onPressed: () {
createUser();
Navigator.pop(context);
},
child: const Text("Registrieren")),
TextButton(
onPressed: () {
if (checkSignin()) {
Navigator.pop(context);
}
},
child: const Text("Anmelden")),
],
);
},
context: buildcontext,
);
}
class MessageList extends StatefulWidget {
MessageList({Key? key}) : super(key: key);
final messageDao = MessageDao();
@override
MessageListState createState() => MessageListState();
}
CodePudding user response:
The call to createUserWithEmailAndPassword
returns a Future
, which can either succeed or fail. But a failure of the Future
only gets translates to an exception if you await
the call.
So:
try {
credential = await auth.createUserWithEmailAndPassword(
email: emailController.text, password: passwordController.text);
} catch (e) {
print('==================');
print('This never gets executed');
print(e);
}
If you'd like to learn more about this, I recommend watching this video: Firebase Authentication in Flutter (The Boring Flutter Development Show, Ep. 55) - YouTube.