尝试更新Firebase数据库中的userData时出现以下错误
E/flutter ( 4756): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: PlatformException(Error performing updateData, NOT_FOUND: No document to update: projects/(DBname)/databases/(default)/documents/userData/ckua6TCjc2Dx76W6efuV, null)
这是我的UserData模型类
class UserData {
// String userId;
String id;
String firstName;
String lastName;
String phoneNumber;
String role;
String streetAddress;
String city;
String state;
String postcode;
String country;
Timestamp createdAt;
Timestamp updatedAt;
UserData();
UserData.fromMap(Map<String, dynamic> data) {
id = data['id'];
// userId = data['user_id'];
firstName = data['first_name'];
lastName = data['last_name'];
phoneNumber = data['phone_number'];
role = data['role'];
streetAddress = data['street_address'];
city = data['city'];
postcode = data['postcode'];
state = data['state'];
country = data['country'];
createdAt = data['created_at'];
updatedAt = data['updated_at'];
}
Map<String, dynamic> toMap() {
return {
'id': id,
// 'user_id': userId,
'first_name': firstName,
'last_name': lastName,
'phone_number': phoneNumber,
'role': role,
'street_address': streetAddress,
'city': city,
'postcode': postcode,
'state': state,
'country': country,
'created_at': createdAt,
'updated_at': updatedAt,
};
}
}
这是我的UserDataNotifier类
class UserDataNotifier with ChangeNotifier {
UserData _loggedInUserData;
Query userDataCollection = Firestore.instance.collection('userData');
UserData get loggedInUserData => _loggedInUserData;
set loggedInUserData(UserData userData) {
_loggedInUserData = userData;
notifyListeners();
}
getUserData(UserDataNotifier userDataNotifier) async {
await userDataCollection
.orderBy('created_at', descending: true)
.getDocuments();
notifyListeners();
}
Future updateUserData(UserData userData, bool isUpdating) async {
CollectionReference userDataRef =
await Firestore.instance.collection('userData');
if (isUpdating) {
userData.updatedAt = Timestamp.now();
await userDataRef.document(userData.id).updateData(userData.toMap());
print('updated userdata with id: ${userData.id}');
} else {
userData.createdAt = Timestamp.now();
DocumentReference documentReference =
await userDataRef.add(userData.toMap());
userData.id = documentReference.documentID;
print('created userdata successfully with id: ${userData.id}');
await documentReference.setData(userData.toMap(), merge: true);
}
notifyListeners();
}
}
这是我的编辑个人资料屏幕,可以调用我的userNotifier
class ProfileFormScreen extends StatefulWidget {
static const String id = 'profile_form';
@override
_ProfileFormScreenState createState() => _ProfileFormScreenState();
}
class _ProfileFormScreenState extends State<ProfileFormScreen> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
UserData _userData;
//global declarations
String selectedBusinessTypeDropDownValue = 'Fashion';
String selectedCurrencyDropDownValue = 'NGN: Nigerian Naira';
String selectedCountryDropDownValue = 'Nigeria';
String email;
_saveUserData(BuildContext context) {
UserDataNotifier userNotifier =
Provider.of<UserDataNotifier>(context, listen: false);
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
userNotifier.updateUserData(_userData, true);
Navigator.pop(context);
}
@override
void initState() {
super.initState();
UserDataNotifier userDataNotifier =
Provider.of<UserDataNotifier>(context, listen: false);
if (userDataNotifier.loggedInUserData != null) {
_userData = userDataNotifier.loggedInUserData;
} else {
_userData = UserData();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Profile'),
),
body: SingleChildScrollView(
padding: EdgeInsets.only(top: 20.0),
child: Form(
autovalidate: true,
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
LabelTextPadding(text: 'Business Information'),
//business name
RegularTextPadding(regText: 'Business Name'),
_buildBusinessName(),
//business type
RegularTextPadding(regText: 'Business Type'),
_buildBusinessType(),
//Trading currency
RegularTextPadding(regText: 'Trading Currency'),
_buildTradingCurrency(),
//business location
RegularTextPadding(regText: 'Location'),
//address 1
_buildAddress(),
//city
_buildCityField(),
//postcode
_buildPostcode(),
//state
_buildStateField(),
//country
_buildCountry(),
SizedBox(
height: 20.0,
),
DividerClass(),
SizedBox(
height: 20.0,
),
//Personal information
LabelTextPadding(
text: 'Personal Information',
),
_buildFirstNameField(),
_buildLastNameField(),
_buildPhoneNumberField(),
// _buildEmailField(),
_buildButtons(),
],
),
),
),
);
}
_buildBusinessName() {
if (_userData.businessName == null) {
return PaddedInputTextFormField(
hintText: 'update business name',
onSaved: (value) {
_userData.businessName = value;
},
);
} else {
return PaddedInputTextFormField(
inputValue: _userData.businessName,
onSaved: (value) {
_userData.businessName = value;
},
);
}
}
_buildBusinessType() {
return Padding(
padding: const EdgeInsets.all(20.0),
child: DropdownButton(
value: _userData.businessType == null
? selectedBusinessTypeDropDownValue
: _userData.businessType,
icon: Icon(FontAwesomeIcons.caretDown),
elevation: 15,
underline: Container(
height: 2,
color: kThemeStyleButtonFillColour,
),
items: businessType
.map(
(businessType) => DropdownMenuItem(
value: businessType, child: Text(businessType)),
)
.toList(),
onChanged: (newValue) {
setState(() {
selectedBusinessTypeDropDownValue = newValue;
_userData.businessType = newValue;
});
},
),
);
}
_buildTradingCurrency() {
return Padding(
padding: const EdgeInsets.all(20.0),
child: DropdownButton(
value: _userData.tradingCurrency == null
? selectedCurrencyDropDownValue
: _userData.tradingCurrency,
icon: Icon(FontAwesomeIcons.caretDown),
elevation: 15,
underline: Container(
height: 2,
color: kThemeStyleButtonFillColour,
),
items: tradingCurrency
.map(
(tradingCurrency) => DropdownMenuItem(
value: tradingCurrency, child: Text(tradingCurrency)),
)
.toList(),
onChanged: (newValue) {
setState(() {
selectedCurrencyDropDownValue = newValue;
_userData.tradingCurrency = newValue;
});
},
),
);
}
_buildAddress() {
if (_userData.streetAddress == null) {
return PaddedInputTextFormField(
hintText: 'address 1',
onSaved: (value) {
_userData.streetAddress = value;
},
);
} else {
return PaddedInputTextFormField(
inputValue: _userData.streetAddress,
onSaved: (value) {
_userData.streetAddress = value;
},
);
}
}
_buildCityField() {
if (_userData.city == null) {
return PaddedInputTextFormField(
hintText: 'update city',
onSaved: (value) {
_userData.city = value;
},
);
} else {
return PaddedInputTextFormField(
inputValue: _userData.city,
onSaved: (value) {
_userData.city = value;
},
);
}
}
_buildPostcode() {
if (_userData.postcode == null) {
return PaddedInputTextFormField(
hintText: 'update postcode',
onSaved: (value) {
_userData.postcode = value;
},
);
} else {
return PaddedInputTextFormField(
inputValue: _userData.postcode,
onSaved: (value) {
_userData.postcode = value;
},
);
}
}
_buildStateField() {
if (_userData.state == null) {
return PaddedInputTextFormField(
hintText: 'update state',
onSaved: (value) {
_userData.state = value;
},
);
} else {
return PaddedInputTextFormField(
inputValue: _userData.state,
onSaved: (value) {
_userData.state = value;
},
);
}
}
_buildCountry() {
return Padding(
padding: const EdgeInsets.all(20.0),
child: DropdownButton(
value: _userData.country == null
? selectedCountryDropDownValue
: _userData.country,
icon: Icon(FontAwesomeIcons.caretDown),
elevation: 15,
underline: Container(
height: 2,
color: kThemeStyleButtonFillColour,
),
items: country
.map(
(country) =>
DropdownMenuItem(value: country, child: Text(country)),
)
.toList(),
onChanged: (newValue) {
setState(() {
selectedCountryDropDownValue = newValue;
_userData.country = newValue;
});
},
),
);
}
//user personal info build
_buildFirstNameField() {
if (_userData.firstName == null) {
return PaddedInputTextFormField(
hintText: 'update first name',
onSaved: (value) {
_userData.firstName = value;
},
);
} else {
return PaddedInputTextFormField(
inputValue: _userData.firstName,
onSaved: (value) {
_userData.firstName = value;
},
);
}
}
_buildLastNameField() {
if (_userData.lastName == null) {
return PaddedInputTextFormField(
hintText: 'update last name',
onSaved: (value) {
_userData.lastName = value;
},
);
} else {
return PaddedInputTextFormField(
inputValue: _userData.lastName,
onSaved: (value) {
_userData.lastName = value;
},
);
}
}
_buildPhoneNumberField() {
if (_userData.phoneNumber == null) {
return PaddedInputTextFormField(
hintText: 'update phone number',
onSaved: (value) {
_userData.phoneNumber = value;
},
);
} else {
return PaddedInputTextFormField(
inputValue: _userData.lastName,
onSaved: (value) {
_userData.phoneNumber = value;
},
);
}
}
//build email form field
_buildEmailField() {
FutureBuilder<String>(
future: AuthProvider.of(context).auth.getCurrentUserEmail(),
// ignore: missing_return
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
return PaddedEmailInputTextField(
emailInput: snapshot.data,
onSaved: (value) => email = value,
);
},
);
}
_buildButtons() {
return Padding(
padding: const EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Buttons(
onPressedButton: () {
Navigator.pop(context);
},
buttonLabel: 'Cancel',
buttonColour: kThemeStyleButtonFillColour,
buttonTextStyle: kThemeStyleButton),
SizedBox(
width: 15.0,
),
Buttons(
onPressedButton: () => _saveUserData(context),
buttonLabel: 'Save',
buttonColour: kThemeStyleButtonFillColour,
buttonTextStyle: kThemeStyleButton),
],
),
);
}
}
我可能会丢失什么?我不确定如何解决我收到的错误。还看到其他在线开发人员也遇到了类似的问题,但是没有答案/线索很奏效。
谢谢。
答案 0 :(得分:0)
所以我弄清楚了为什么会出现该错误。问题是我在updateUserData()方法中将isUpating设置为true,默认情况下,当在我的应用程序中没有初始数据保存到数据库时,该值为true。
没有现有数据时,我必须使用
documentReference.setData(userData.toMap())
因为目前没有要更新的内容
我希望这对寻求解决方案的人有所帮助。