I'm trying to implement Firebase authentication into my app with Flutter and my coding worked fine initially, although since I have migrated the project to null safety the authentication no longer works. I think I have 'isolated' where that is.
For example, if we take my password reset TextField, this is what the TextField looks like in terms of the code:
TextField _buildEmailTextField() {
return TextField(
controller: _emailController,
focusNode: _emailFocusNode,
decoration: InputDecoration(
labelText: 'Email',
hintText: 'email@address.com',
errorText: model.emailErrorText,
enabled: model.isLoading == false,
),
autocorrect: false,
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.done,
onChanged: model.updateEmail,
onEditingComplete: _submit,
);
}
Of course, to handle changes to the TextField, you can see that I have added an updateEmail function onChanged: model.updateEmail
. The function itself looks like this:
void updateEmail(String email) => updateWith(email: email);
And the updateWith function looks like this:
void updateWith({
String email = '',
bool isLoading = false,
bool submitted = false,
}) {
this.email = email;
this.isLoading = isLoading;
this.submitted = submitted;
notifyListeners();
}
Prior to null safety, I didn't need to initialise the variables in updateWith
with a value, so it would have looked like this:
void updateWith({
String email,
bool isLoading,
bool submitted,
}) {
this.email = email;
this.isLoading = isLoading;
this.submitted = submitted;
notifyListeners();
}
The error from Firebase is:
[firebase_auth/missing-email] An email address must be provided
And I think this is caused by the fact that I am now having to initialise the email
variable in updateWith
, and I am using an empty string. Therefore, even though I am typing in an email into the TextField, when I submit, it submits the empty string, so that Firebase tells me I haven't submitted an email. I have tried it instead using email as a nullable value, like so:
void updateWith({
String? email,
bool isLoading = false,
bool submitted = false,
}) {
this.email = email!;
this.isLoading = isLoading;
this.submitted = submitted;
notifyListeners();
}
But then that gives me the error:
Null check operator used on a null value
How do I make my updateWith function work now that I have migrated to null safety? As I say, it worked fine prior to null safety, so I am confident with the logic. It's just that having to initialise email
with a variable within the function now means that initial variable is submitted to firebase, rather than the typed-in email address. Is there a way to make this work, or a way I can rewrite my updateEmail
and updateWith
functions, so that they don't have to be initialised with a value?
If you need me to provide any additional information, I would be happy to. Thanks for the advice!
The method is very unintuitive for Dart/Flutter developers, unless you do it using the common pattern. The point of those optional parameters in methods like this normally is to pass only a few of them, leaving the rest untouched. So for example, you could call updateWith(email: 'test@example.com')
and only the email
will be updated but isLoading
and submitted
will remain unchanged. You can only achieve this if the parameters are nullable, so you have a marker/value for "wasn't set at all" that you can check for.
For example:
void updateWith({
String? email,
bool? isLoading,
bool? submitted,
}) {
this.email = email ?? this.email;
this.isLoading = isLoading ?? this.isLoading;
this.submitted = submitted ?? this.submitted;
notifyListeners();
}
If email
is a required parameter and the other two will be set to defaults anyway, you don't need named parameters at all. Just make it a normal method with normal positional parameters.