Reputation: 6766
I've a setting page in my app that a user can edit to update details. The data screen consists of two Two Textfields and a profile avatar. The app has google(and email&password)as the auth providers. So when the user signs up for the first time I have a method that presents the data to the user.
void readLocal() async {
controllerName = new TextEditingController(text: AuthProvider.of(context).userData.name);
print(controllerName);
controllerEmail = new TextEditingController(text: AuthProvider.of(context).userData.email);
avatarUrl= AuthProvider.of(context).userData.avatarUrl;
// controllerPhoneNumber= new TextEditingController(text: AuthProvider.of(context).userData.phoneNumber);
// Force refresh input
setState(() {});
}
The data is presented as expected. The method is called in
@override
void didChangeDependencies() {
readLocal();
}
To make sure initState has completed. I have an update button that isn't behaving as I would like. When I edit both fields: both of the fields update and the correct writes are sent to Firestore. However if I update one TextField
, and press update I lose the data in the other TextField
(an empty string is written to Firestore) and vice versa. And if I press the update without editing either fields, both the fields in Firestore end up with empty strings. Here is my update function
void handleUpdateData() {
focusName.unfocus();
focusEmail.unfocus();
setState(() {
isLoading = true;
});
AuthProvider.of(context).userData.docRef.updateData({'name': name, 'email': email,'avatarUrl':avatarUrl}).then((data) async{
print('@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@');
setState(() {
isLoading = false;
});
Fluttertoast.showToast(msg: "Update success");
}).catchError((err) {
setState(() {
isLoading = false;
});
Fluttertoast.showToast(msg: err.toString());
});
}
here is a gist of the dart file. I presume by not editing the fields and then pressing the update button, the update function takes an empty string to update with and write this to Firestore. How do I prevent this?
Upvotes: 1
Views: 3755
Reputation: 598668
If you tell Firestore to set a field to an empty string, it will set that field to an empty string. If you don't want Firestore to modify a field, you should not specify that field in the call to updateDate(...)
.
In practice this means you need to conditionally populate the Map
of values, with something like this:
Map<String, dynamic> values = new Map<String,dynamic>();
if (name?.isEmpty ?? true) values["name"] = name;
if (email?.isEmpty ?? true) values["email"] = email;
if (avatarUrl?.isEmpty ?? true) values["avatarUrl"] = avatarUrl;
AuthProvider.of(context).userData.docRef.updateData(values).then((data) async{
...
For the logic of the check for empty strings, see Dart null / false / empty checking: How to write this shorter?
Upvotes: 2