我的应用程序中有一个设置页面,用户可以编辑该页面以更新详细信息。数据屏幕包含两个“两个文本字段”和一个配置文件头像。该应用程序具有Google(以及电子邮件和密码)作为身份验证提供程序。因此,当用户首次注册时,我有一种向用户显示数据的方法。
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),反之亦然。而且,如果我不编辑任何字段而按更新,则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());
});
}
这是gist 飞镖文件。我假设不编辑这些字段,然后按更新按钮,更新功能将使用一个空字符串进行更新并将其写入Firestore。我该如何预防?
答案 0 :(得分:1)
如果您告诉Firestore将字段设置为空字符串,它将将该字段设置为空字符串。如果您不希望Firestore修改字段,则不应在对updateDate(...)
的调用中指定该字段。
实际上,这意味着您需要有条件地填充值Map
,如下所示:
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{
...
有关检查空字符串的逻辑,请参见Dart null / false / empty checking: How to write this shorter?