Flatter Firebase-在Firestore上更改图像时,更新用户配置文件图像会返回错误

Flatter Firebase-在Firestore上更改图像时,更新用户配置文件图像会返回错误,firebase,flutter,google-cloud-firestore,firebase-storage,stream-builder,Firebase,Flutter,Google Cloud Firestore,Firebase Storage,Stream Builder,我有一个带有个人资料页面的应用程序,我想在那里有个人资料图片,用户可以随时更新 我现在拥有的代码执行以下操作:StreamBuilder将使用当前用户UID获取Firestore集合,并从snapshot.data获取文档“URL”来构建Image.network 问题: File _image; Future getImage(bool gallery) async { ImagePicker picker = ImagePicker(); PickedFile pick

我有一个带有个人资料页面的应用程序,我想在那里有个人资料图片,用户可以随时更新

我现在拥有的代码执行以下操作:StreamBuilder将使用当前用户UID获取Firestore集合,并从snapshot.data获取文档“URL”来构建Image.network

问题:

File _image;

  Future getImage(bool gallery) async {
    ImagePicker picker = ImagePicker();
    PickedFile pickedFile;
    // Let user select photo from gallery
    if (gallery) {
      pickedFile = await picker.getImage(
        source: ImageSource.gallery,
      );
    }
    setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
        uploadFile(_image);
        uploadToFirebase(); // Use if you only need a single picture
      } else {
        print('No image selected.');
      }
    });
  }

  Future<String> uploadFile(File image) async {
    String downloadURL;
    Reference ref = FirebaseStorage.instance
        .ref()
        .child("images/${_firebaseAuth.currentUser.uid}");
    await ref.putFile(image);
    downloadURL = await ref.getDownloadURL();
    return downloadURL;
  }

  Future uploadToFirebase() async {
    final CollectionReference users =
        _firebaseFirestore.collection("Companies");
    final String uid = _firebaseAuth.currentUser.uid;

    String url = await uploadFile(
        _image); // this will upload the file and store url in the variable 'url'
    await users.doc(uid).update({'url': url});
    final result = await users.doc(uid).get();
    return result.data()["url"];
  }
Container(
                                child: _image != null
                                    ? Column(
                                        children: [
                                          StreamBuilder(
                                            stream: _firebaseFirestore
                                                .collection("Companies")
                                                .doc(_firebaseAuth
                                                    .currentUser.uid)
                                                .snapshots(),
                                            builder: (BuildContext context,
                                                AsyncSnapshot snapshot) {
                                              if (snapshot.connectionState ==
                                                  ConnectionState.waiting) {
                                                return Text("Loading");
                                              }
                                              return Image.network(
                                                snapshot.data.data()["url"],
                                                width: 100,
                                                height: 100,
                                              );
                                            },
                                          ),
                                        ],
                                      )
                                    : Container(
                                        decoration: BoxDecoration(
                                          color: Colors.grey[200],
                                          borderRadius:
                                              BorderRadius.circular(50),
                                        ),
                                        width: 100,
                                        height: 100,
                                        child: Icon(
                                          Icons.camera_alt,
                                          color: Colors.grey[800],
                                        ),
                                      ),
                              ),
第一次,当用户创建一个新用户时,图像上有一个占位符,当用户从gallery中选择一个新图像时,它将在更新集合和更新UI之间返回一个错误,然后更改为新图像。此外,根据图像的大小,更改图像需要花费大量时间

如果有人能给我一个不同的方法,我会很感激

上传到Firestore的功能:

File _image;

  Future getImage(bool gallery) async {
    ImagePicker picker = ImagePicker();
    PickedFile pickedFile;
    // Let user select photo from gallery
    if (gallery) {
      pickedFile = await picker.getImage(
        source: ImageSource.gallery,
      );
    }
    setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
        uploadFile(_image);
        uploadToFirebase(); // Use if you only need a single picture
      } else {
        print('No image selected.');
      }
    });
  }

  Future<String> uploadFile(File image) async {
    String downloadURL;
    Reference ref = FirebaseStorage.instance
        .ref()
        .child("images/${_firebaseAuth.currentUser.uid}");
    await ref.putFile(image);
    downloadURL = await ref.getDownloadURL();
    return downloadURL;
  }

  Future uploadToFirebase() async {
    final CollectionReference users =
        _firebaseFirestore.collection("Companies");
    final String uid = _firebaseAuth.currentUser.uid;

    String url = await uploadFile(
        _image); // this will upload the file and store url in the variable 'url'
    await users.doc(uid).update({'url': url});
    final result = await users.doc(uid).get();
    return result.data()["url"];
  }
Container(
                                child: _image != null
                                    ? Column(
                                        children: [
                                          StreamBuilder(
                                            stream: _firebaseFirestore
                                                .collection("Companies")
                                                .doc(_firebaseAuth
                                                    .currentUser.uid)
                                                .snapshots(),
                                            builder: (BuildContext context,
                                                AsyncSnapshot snapshot) {
                                              if (snapshot.connectionState ==
                                                  ConnectionState.waiting) {
                                                return Text("Loading");
                                              }
                                              return Image.network(
                                                snapshot.data.data()["url"],
                                                width: 100,
                                                height: 100,
                                              );
                                            },
                                          ),
                                        ],
                                      )
                                    : Container(
                                        decoration: BoxDecoration(
                                          color: Colors.grey[200],
                                          borderRadius:
                                              BorderRadius.circular(50),
                                        ),
                                        width: 100,
                                        height: 100,
                                        child: Icon(
                                          Icons.camera_alt,
                                          color: Colors.grey[800],
                                        ),
                                      ),
                              ),

首先,在代码中,您将上载文件两次:一次在setState()中,另一次在uploadToFirebase()中

当snapshot.connectionState与connectionState.done不同时,您可以尝试显示加载文本:

if (!snapshot.hasData) {
    return Text("Loading");
}

return Image.network(
    snapshot.data.data()["url"],
    width: 100,
    height: 100,
);

首先,在代码中,您将上载文件两次:一次在setState()中,另一次在uploadToFirebase()中

当snapshot.connectionState与connectionState.done不同时,您可以尝试显示加载文本:

if (!snapshot.hasData) {
    return Text("Loading");
}

return Image.network(
    snapshot.data.data()["url"],
    width: 100,
    height: 100,
);

编辑:你能告诉我这是否有效吗

File _image;
bool _loading = false;
final FirebaseStorage _storage = FirebaseStorage(storageBucket:'gs://LINK.com'); //find your link in your storage console like this screenshot https://i.imgur.com/gW35HJk.png
StorageUploadTask _uploadTask;

  Future getImage(bool gallery) async {
    this.setState((){
    _loading = true;
    });
    ImagePicker picker = ImagePicker();
    PickedFile pickedFile;
    // Let user select photo from gallery
    if (gallery) {
      pickedFile = await picker.getImage(
        source: ImageSource.gallery,
      );
    }
    setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
        uploadFile(_image);
      } else {
        print('No image selected.');
        this.setState((){
        _loading = false;
        });

      }
    });
  }

  Future<String> uploadFile(File image) async {
    String downloadURL;
    String filePath = "images/${_firebaseAuth.currentUser.uid}";
    setState(() {
      _uploadTask = _storage.ref().child(filePath).putFile(image).onComplete;
    });
    var imageUrl = await (await 
    _uploadTask.onComplete).ref.getDownloadURL();
    downloadURL = imageUrl.toString();
    
    uploadToFirebase(downloadURL);
  }

  Future uploadToFirebase(downloadURL) async {
    final CollectionReference users =
        _firebaseFirestore.collection("Companies");
    final String uid = _firebaseAuth.currentUser.uid;

    String url = downloadURL // this will upload the file and store url in the variable 'url'
    await users.doc(uid).update({'url': url});
    final result = await users.doc(uid).get();

    if (result != null) {
       setState((){
            getImage().onComplete{
            loading = false;
       }
       return result.data()["url"];
    }
    });
  }

----------Below is before edit---------------

Use a bool to determine if loading is complete or not

bool _loading = false;

    Future getImage(bool gallery) async {
        this.setState((){
        _loading = true;
        });
    
        ImagePicker picker = ImagePicker();
        PickedFile pickedFile;
        // Let user select photo from gallery
        if (gallery) {
          pickedFile = await picker.getImage(
            source: ImageSource.gallery,
          );
        }
        setState(() {
          if (pickedFile != null) {
            _image = File(pickedFile.path);
            uploadFile(_image);
            uploadToFirebase(); // Use if you only need a single picture'
     setState(() {
          _loading = false;
        });
          } else {
            print('No image selected.');
            setState(() {
          _loading = false;
        });
          }
        });
      }
File\u图像;
bool\u加载=假;
最终FirebaseStorage _storage=FirebaseStorage(storageBucket:'gs://LINK.com')//在存储控制台中找到链接,如下图所示https://i.imgur.com/gW35HJk.png
StorageUploadTask\u uploadTask;
未来getImage(布尔图库)异步{
此.setState(){
_加载=真;
});
ImagePicker-picker=ImagePicker();
PickedFile PickedFile;
//让用户从图库中选择照片
国际单项体育联合会(画廊){
pickedFile=wait picker.getImage(
来源:ImageSource.gallery,
);
}
设置状态(){
if(pickedFile!=null){
_image=文件(pickedFile.path);
上传文件(_图像);
}否则{
打印('未选择图像');
此.setState(){
_加载=假;
});
}
});
}
未来上传文件(文件映像)异步{
字符串下载URL;
字符串filePath=“images/${u firebaseAuth.currentUser.uid}”;
设置状态(){
_uploadTask=\u storage.ref().child(filePath).putFile(image).onComplete;
});
var imageUrl=await(等待
_uploadTask.onComplete).ref.getDownloadURL();
downloadURL=imageUrl.toString();
上传至Firebase(下载URL);
}
未来上传到Firebase(下载URL)异步{
最终收集参考用户=
_firebaseFirestore.集合(“公司”);
最终字符串uid=\u firebaseAuth.currentUser.uid;
String url=downloadURL//这将上载文件并将url存储在变量“url”中
等待users.doc(uid.update({'url':url});
最终结果=wait users.doc(uid.get();
如果(结果!=null){
设置状态(){
getImage().onComplete{
加载=假;
}
返回result.data()[“url”];
}
});
}
----------下面是编辑之前的内容---------------
使用bool确定加载是否完成
bool\u加载=假;
未来getImage(布尔图库)异步{
此.setState(){
_加载=真;
});
ImagePicker-picker=ImagePicker();
PickedFile PickedFile;
//让用户从图库中选择照片
国际单项体育联合会(画廊){
pickedFile=wait picker.getImage(
来源:ImageSource.gallery,
);
}
设置状态(){
if(pickedFile!=null){
_image=文件(pickedFile.path);
上传文件(_图像);
uploadToFirebase();//如果只需要一张图片,请使用'
设置状态(){
_加载=假;
});
}否则{
打印('未选择图像');
设置状态(){
_加载=假;
});
}
});
}

编辑:你能告诉我这是否有效吗

File _image;
bool _loading = false;
final FirebaseStorage _storage = FirebaseStorage(storageBucket:'gs://LINK.com'); //find your link in your storage console like this screenshot https://i.imgur.com/gW35HJk.png
StorageUploadTask _uploadTask;

  Future getImage(bool gallery) async {
    this.setState((){
    _loading = true;
    });
    ImagePicker picker = ImagePicker();
    PickedFile pickedFile;
    // Let user select photo from gallery
    if (gallery) {
      pickedFile = await picker.getImage(
        source: ImageSource.gallery,
      );
    }
    setState(() {
      if (pickedFile != null) {
        _image = File(pickedFile.path);
        uploadFile(_image);
      } else {
        print('No image selected.');
        this.setState((){
        _loading = false;
        });

      }
    });
  }

  Future<String> uploadFile(File image) async {
    String downloadURL;
    String filePath = "images/${_firebaseAuth.currentUser.uid}";
    setState(() {
      _uploadTask = _storage.ref().child(filePath).putFile(image).onComplete;
    });
    var imageUrl = await (await 
    _uploadTask.onComplete).ref.getDownloadURL();
    downloadURL = imageUrl.toString();
    
    uploadToFirebase(downloadURL);
  }

  Future uploadToFirebase(downloadURL) async {
    final CollectionReference users =
        _firebaseFirestore.collection("Companies");
    final String uid = _firebaseAuth.currentUser.uid;

    String url = downloadURL // this will upload the file and store url in the variable 'url'
    await users.doc(uid).update({'url': url});
    final result = await users.doc(uid).get();

    if (result != null) {
       setState((){
            getImage().onComplete{
            loading = false;
       }
       return result.data()["url"];
    }
    });
  }

----------Below is before edit---------------

Use a bool to determine if loading is complete or not

bool _loading = false;

    Future getImage(bool gallery) async {
        this.setState((){
        _loading = true;
        });
    
        ImagePicker picker = ImagePicker();
        PickedFile pickedFile;
        // Let user select photo from gallery
        if (gallery) {
          pickedFile = await picker.getImage(
            source: ImageSource.gallery,
          );
        }
        setState(() {
          if (pickedFile != null) {
            _image = File(pickedFile.path);
            uploadFile(_image);
            uploadToFirebase(); // Use if you only need a single picture'
     setState(() {
          _loading = false;
        });
          } else {
            print('No image selected.');
            setState(() {
          _loading = false;
        });
          }
        });
      }
File\u图像;
bool\u加载=假;
最终FirebaseStorage _storage=FirebaseStorage(storageBucket:'gs://LINK.com')//在存储控制台中找到链接,如下图所示https://i.imgur.com/gW35HJk.png
StorageUploadTask\u uploadTask;
未来getImage(布尔图库)异步{
此.setState(){
_加载=真;
});
ImagePicker-picker=ImagePicker();
PickedFile PickedFile;
//让用户从图库中选择照片
国际单项体育联合会(画廊){
pickedFile=wait picker.getImage(
来源:ImageSource.gallery,
);
}
设置状态(){
if(pickedFile!=null){
_image=文件(pickedFile.path);
上传文件(_图像);
}否则{
打印('未选择图像');
此.setState(){
_加载=假;
});
}
});
}
未来上传文件(文件映像)异步{
字符串下载URL;
字符串filePath=“images/${u firebaseAuth.currentUser.uid}”;
设置状态(){
_uploadTask=\u storage.ref().child(filePath).putFile(image).onComplete;
});
var imageUrl=await(等待
_uploadTask.onComplete).ref.getDownloadURL();
downloadURL=imageUrl.toString();
上传至Firebase(下载URL);
}
未来上传到Firebase(下载URL)异步{
最终收集参考用户=
_firebaseFirestore.集合(“公司”);
最终字符串uid=\u firebaseAuth.currentUser.uid;
String url=downloadURL//这将上载文件并将url存储在变量“url”中
等待users.doc(uid.update({'url':url});
最终结果=wait users.doc(uid.get();
如果(结果!=null){
设置状态(){
getImage().onComplete{
加载=假;
}
返回result.data()[“url”];
}
});
}
----------下面是