Flutter 如何有条件地更新云Firestore中的数据?

Flutter 如何有条件地更新云Firestore中的数据?,flutter,google-cloud-firestore,Flutter,Google Cloud Firestore,我的应用程序中有一个设置页面,用户可以编辑该页面以更新详细信息。数据屏幕由两个文本字段和一个配置文件化身组成。该应用程序使用谷歌(以及电子邮件和密码)作为身份验证提供商。因此,当用户第一次注册时,我有一种方法可以将数据呈现给用户 void readLocal() async { controllerName = new TextEditingController(text: AuthProvider.of(context).userData.name); print(contr

我的应用程序中有一个设置页面,用户可以编辑该页面以更新详细信息。数据屏幕由两个文本字段和一个配置文件化身组成。该应用程序使用谷歌(以及电子邮件和密码)作为身份验证提供商。因此,当用户第一次注册时,我有一种方法可以将数据呈现给用户

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(() {});
  }
数据如预期所示。在中调用该方法

 @override
  void didChangeDependencies() {
    readLocal();

  }
以确保initState已完成。我有一个更新按钮,它的行为不符合我的要求。当我编辑两个字段时:两个字段都会更新,并且正确的写入会发送到Firestore。但是,如果我更新一个
TextField
,然后按update,我将丢失另一个
TextField
(一个空字符串写入Firestore),反之亦然。如果我在不编辑任何字段的情况下按update,Firestore中的两个字段都将以空字符串结束。这是我的更新功能

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());
    });
  }
这是一个
省道锉刀。我假定,通过不编辑字段,然后按下更新按钮,更新函数将获取一个空字符串进行更新,并将其写入Firestore。如何防止这种情况发生?

如果您告诉Firestore将字段设置为空字符串,它会将该字段设置为空字符串。如果不希望Firestore修改字段,则不应在对
updateDate(…)
的调用中指定该字段

实际上,这意味着您需要有条件地填充值的
映射
,如下所示:

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{
  ...
映射值=新映射();
如果(name?.isEmpty??true)值[“name”]=name;
如果(email?.isEmpty±true)值[“email”]=email;
如果(avatarUrl?.isEmpty??true)值[“avatarUrl”]=avatarUrl;
AuthProvider.of(context).userData.docRef.updateData(values).then((data)async{
...

有关检查空字符串的逻辑,请参见

感谢条件
映射
,但它仍然在FireStore中设置空字段。您自己调试过吗?可能是
名称?.isEmpty??true
需要稍微不同才能捕捉到您的条件。