flutter
flutter

Reputation: 6766

How to conditionally update data in Cloud Firestore?

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

Answers (1)

Frank van Puffelen
Frank van Puffelen

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

Related Questions