将文档保存到Flutter中的Firebase Cloud数据库时出错

问题描述 投票:0回答:1

我具有执行以下操作的数据库服务:

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<…>

任何帮助将不胜感激!

firebase flutter dart google-cloud-firestore firebase-storage
1个回答
0
投票

只需按照以下步骤更改图像上传方法,

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;
  }
© www.soinside.com 2019 - 2024. All rights reserved.