在Flatter中将文档保存到Firebase云数据库时出错
我有一个数据库服务,它执行以下操作:在Flatter中将文档保存到Firebase云数据库时出错,firebase,flutter,dart,google-cloud-firestore,firebase-storage,Firebase,Flutter,Dart,Google Cloud Firestore,Firebase Storage,我有一个数据库服务,它执行以下操作: class DatabaseService { final String uid; DatabaseService({this.uid}); //collection reference final CollectionReference userCollection = Firestore.instance.collection('users'); //USER METHODS //update user data Futu
class DatabaseService {
final String uid;
DatabaseService({this.uid});
//collection reference
final CollectionReference userCollection = Firestore.instance.collection('users');
//USER METHODS
//update user data
Future updateUserData(String username, int colorData, String avatar) async {
return await userCollection.document(uid).setData(
{
'username': username,
'color': colorData,
'avatar': avatar
}
);
}
数据通过以下形式发送:
class SettingsForm extends StatefulWidget {
SettingsForm({Key key}) : super(key: key);
@override
_SettingsFormState createState() => _SettingsFormState();
}
class _SettingsFormState extends State<SettingsForm> {
final _formKey = GlobalKey<FormState>();
//form values
String _currentUsername;
int _currentColor;
String _currentAvatar;
File _avatarFile;
//avatar picker
Future chooseAvatar() async {
File image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_avatarFile = image;
});
}
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return StreamBuilder<UserData>(
stream: DatabaseService(uid: user.uid).userData,
builder: (context, snapshot) {
if(snapshot.hasData){
UserData userData = snapshot.data;
if(_currentColor == null){
_currentColor = userData.colorData;
}
avatarColor = Color(_currentColor);
return Form(
key: _formKey,
child: Column(
children: <Widget>[
Row(
children: <Widget>[
FlatButton.icon(
label: Text("Save"),
icon: Icon(Icons.save),
onPressed: () async {
if(_formKey.currentState.validate()){
String url = await StorageService().addOrUpdateUser(_avatarFile, user.uid, currentFileUrl: userData.avatar);
setState(() => _currentAvatar = url);
await DatabaseService(uid: user.uid).updateUserData(
_currentUsername ?? userData.username,
_currentColor ?? userData.color(),
_currentAvatar ?? userData.avatar
);
Navigator.pop(context);
}
},
),
],
),
ListView(
children: <Widget>[
TextFormField(
initialValue: userData.username,
onChanged: (val) => setState(() => _currentUsername = val),
),
Container(
child: _avatarFile == null ?
Column(
children: <Widget>[
ButtonTheme(
minWidth: double.infinity,
child: RaisedButton.icon(
label: Text("Upload Avatar"),
icon: Icon(Icons.photo_library),
elevation: 10,
onPressed: chooseAvatar,
),
),
],
)
: Column(
children: <Widget>[
ButtonTheme(
minWidth: double.infinity,
child: RaisedButton.icon(
label: Text("Remove Avatar"),
icon: Icon(Icons.close),
onPressed: () => setState(()=> _avatarFile = null),
),
),
],
),
),
]
),
],
)
);
}
else{
return Loading();
}
}
);
}
}
类设置窗体扩展StatefulWidget{
setingsform({Key}):super(Key:Key);
@凌驾
_SettingsFormState createState()=>_SettingsFormState();
}
类_设置FormState扩展状态{
final _formKey=GlobalKey();
//形式值
字符串_currentUsername;
int_currentColor;
字符串_currentAvatar;
文件_avatarFile;
//化身选择器
Future chooseAvatar()异步{
File image=wait ImagePicker.pickImage(源:ImageSource.gallery);
设置状态(){
_化身文件=图像;
});
}
@凌驾
小部件构建(构建上下文){
最终用户=提供者(上下文);
返回流生成器(
流:DatabaseService(uid:user.uid).userData,
生成器:(上下文,快照){
if(snapshot.hasData){
UserData UserData=snapshot.data;
如果(_currentColor==null){
_currentColor=userData.colorData;
}
化身颜色=颜色(当前颜色);
报税表(
键:_formKey,
子:列(
儿童:[
划船(
儿童:[
FlatButton.icon(
标签:文本(“保存”),
图标:图标(Icons.save),
onPressed:()异步{
if(_formKey.currentState.validate()){
字符串url=wait-StorageService().addOrUpdateUser(_-avatarFile,user.uid,currentFileUrl:userData.avatar);
设置状态(()=>_currentAvatar=url);
等待数据库服务(uid:user.uid)(
_currentUsername??userData.username,
_currentColor??userData.color(),
_currentAvatar??userData.avatar
);
Navigator.pop(上下文);
}
},
),
],
),
列表视图(
儿童:[
TextFormField(
initialValue:userData.username,
一旦更改:(val)=>setState(()=>_currentUsername=val),
),
容器(
子项:_avatarFile==null?
纵队(
儿童:[
钮扣(
minWidth:double.infinity,
子:RaisedButton.icon(
标签:文本(“上传化身”),
图标:图标(图标。照片库),
标高:10,
onPressed:chooseAvatar,
),
),
],
)
:列(
儿童:[
钮扣(
minWidth:double.infinity,
子:RaisedButton.icon(
标签:文本(“移除化身”),
图标:图标(Icons.close),
按下时:()=>设置状态(()=>_avatarFile=null),
),
),
],
),
),
]
),
],
)
);
}
否则{
返回加载();
}
}
);
}
}
存储服务正在执行以下操作:
class StorageService{
final _storage = FirebaseStorage.instance;
final _users = FirebaseStorage.instance.ref().child("/Users/");
Future<String> addOrUpdateUser(File image, String fileName, {String currentFileUrl}) async {
String imageName = fileName + Path.extension(image.path);
StorageReference ref = _users.child(imageName);
StorageUploadTask task = ref.putFile(image);
String url = await (await task.onComplete).ref.getDownloadURL();
print("in Storage");
print(url);
deleteImage(currentFileUrl);
return url;
}
Future deleteImage(String currentFileUrl) async {
final _oldRef = await _storage.getReferenceFromUrl(currentFileUrl);
return _oldRef.delete();
}
类存储服务{
final _storage=FirebaseStorage.instance;
final _users=FirebaseStorage.instance.ref().child(“/users/”);
未来的addOrUpdateUser(文件映像,字符串文件名,{String currentFileUrl})异步{
字符串imageName=fileName+Path.extension(image.Path);
StorageReference ref=\u users.child(imageName);
StorageUploadTask任务=ref.putFile(图像);
字符串url=await(await task.onComplete).ref.getDownloadURL();
打印(“存储中”);
打印(url);
deleteImage(currentFileUrl);
返回url;
}
未来删除映像(字符串currentFileUrl)异步{
final _oldRef=wait _storage.getReferenceFromUrl(currentFileUrl);
返回_oldRef.delete();
}
我从复制/粘贴中了解到大括号等存在一些不平衡,但代码确实编译并运行了
一旦图像上传到Firebase存储,下载URL就被正确地发送回小部件,并且状态被成功更新。一旦用户名、颜色和化身被发送到数据库服务,我已经证明数据被正确地发送
由于我不知道的原因,在更新用户文档之前,应用程序正在退出,并且终端显示以下错误:
flutter: in Storage
flutter: https://firebasestorage.googleapis.com/v0/b/xxx-yyy.appspot.com/o/Users%2FpVVUiVsWfudo6NNpr9yQEgfc2tD2.jpg?alt=media&token=0a0a373a-f5be-41f1-9b23-86ad78cdd91c
flutter: In database
flutter: https://firebasestorage.googleapis.com/v0/b/xxx-yyy.appspot.com/o/Users%2FpVVUiVsWfudo6NNpr9yQEgfc2tD2.jpg?alt=media&token=0a0a373a-f5be-41f1-9b23-86ad78cdd91c
Lost connection to device.
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23c4f02e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff50b97b20 objc_exception_throw + 48
2 CoreFoundation 0x00007fff23c4ee6c +[NSException raise:format:] + 188
3 Runner 0x000000010e7a330e +[FIRStoragePath pathFromString:] + 318
4 Runner 0x000000010e797458 -[FIRStorage referenceForURL:] + 88
5 Runner 0x000000010e858f94 -[FLTFirebaseStoragePlugin getReferenceFromUrl:result:] + 212
6 Runner 0x000000010e857690 -[FLTFirebaseStoragePlugin handleMethodCall:result:] + 1536
7 Flutter 0x00000001103abf95 __45-[FlutterMethodChannel setMethodCallHandler:]_block_invoke + 104
8<…>
颤振:在存储中
颤振:https://firebasestorage.googleapis.com/v0/b/xxx-yyy.appspot.com/o/Users%2FpVVUiVsWfudo6NNpr9yQEgfc2tD2.jpg?alt=media&token=0a0a373a-f5be-41f1-9b23-86ad78cdd91c
颤振:在数据库中
颤振:https://firebasestorage.googleapis.com/v0/b/xxx-yyy.appspot.com/o/Users%2FpVVUiVsWfudo6NNpr9yQEgfc2tD2.jpg?alt=media&token=0a0a373a-f5be-41f1-9b23-86ad78cdd91c
与设备的连接中断。
***第一次抛出调用堆栈:
(
0 CoreFoundation 0x00007fff23c4f02e例外预处理+350
1 libobjc.A.dylib 0x00007fff50b97b20 objc_异常_抛出+48
2 CoreFoundation 0x00007fff23c4ee6c+[N异常提升:格式:][188
3运行程序0x000000010e7a330e+[FIRStoragePath pathFromString:][318
4.
Future<String> addOrUpdateUser(File image, String fileName, {String currentFileUrl}) async {
String imageName = fileName + Path.extension(image.path);
StorageReference ref = _users.child(imageName);
StorageUploadTask task = ref.putFile(image);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
String url = await taskSnapshot.ref.getDownloadURL();
deleteImage(currentFileUrl);
return url;
}