我具有执行以下操作的数据库服务:
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();
}
}
);
}
}
存储服务正在执行以下操作:
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();
}
我从复制/粘贴知道花括号之间存在一些不平衡,但代码确实可以编译并运行。
一旦将图像上传到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<…>
任何帮助将不胜感激!
只需按照以下步骤更改图像上传方法,
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;
}