颤抖,试图从存储中更新图片

flutter, trying to update a picture from Storage

我正在尝试上传和更新来自 Firebase 存储的图片。但由于某种原因,这无法正常工作。

情况就是这样;一个用户用他的相机拍了一张照片,所以这张照片上传到我的存储中,所以之后我得到了 url 图片,所以我可以像 NetworkImage(url) 一样使用它来更新图片。

这是当前发生的事情:


假设我没有任何照片。

现在假设我想更新我的个人资料照片,所以我拍了另一张照片,我们称之为 A 所以我上传了这张。

但是如果我用 B 图片再次尝试,由于某种原因图片会更新为 A 图片。


这将是我的代码以及我如何使用此功能。

我有下一个方法,当用户点击他的图片时调用。我等待结果(值)所以当我得到结果时我上传图片。然后,当图片上传时,我只是调用 setState 并将 url 保存到 _imageUrl 变量中。

之后,我将数据库中的“profilePic”属性更改为true

  String _imageUrl = 'assets/profileDefault.jpg';
  bool profilePicture = false;
  io.File profilePic;
  Future getFromCamara() async {
    await ImagePicker().getImage(source: ImageSource.camera).then((value) {
      profilePic = io.File(value.path);
      FirebaseStorage.instance.ref().child('picture').putFile(profilePic);
    }).then((result) {
      var ref = FirebaseStorage.instance.ref().child('picture');
      ref.getDownloadURL().then((loc) => setState(() => _imageUrl = loc));
    });

    try {
      FirebaseFirestore.instance
          .collection('Usuarios')
          .doc(uid)
          .update({'profilePic': true});
    } catch (e) {
      print(e.toString());
    }

所以现在,使用 StreamBuilder,我从我的数据库中得到 profilePic 的结果,如果是 True,我下载 URL,如果不是,我只使用 Asset默认图片

body: StreamBuilder(
        stream: FirebaseFirestore.instance.collection('Usuarios').snapshots(),
        builder: (context, AsyncSnapshot<QuerySnapshot> snapshot1) {

              if (!snapshot1.hasData) {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }

              List<DocumentSnapshot> users = snapshot1.data.docs;

              for (DocumentSnapshot user in users) {
                if (user.id == userID) {
                  profilePicture = user['profilePic'];
                }
              }

              if (profilePicture) {
                FirebaseStorage.instance
                    .ref()
                    .child('picture')
                    .getDownloadURL()
                    .then((loc) => _imageUrl = loc);
              } else {
                _imageUrl = 'assets/profileDefault.jpg';
              }
             
              return Stack(
                alignment: Alignment.center,
                children: <Widget>[
                  Positioned(
                    top: 0,
                    child: Container(
                      color: Color.fromRGBO(255, 0, 0, 70),
                      width: MediaQuery.of(context).size.width,
                      height: MediaQuery.of(context).size.height * .55,
                    ),
                  ),
                  Positioned(
                    top: MediaQuery.of(context).size.height * .015,
                    left: 15,
                    right: 15,
                    child: Container(
                      width: MediaQuery.of(context).size.height * .90,
                      height: 300,
                      padding: EdgeInsets.only(bottom: 10),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: <Widget>[
                          Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              GestureDetector(
                                onTap: () => _setPic(context),
                                child: CircleAvatar(
                                  radius: 79,
                                  backgroundColor: Color(0xFFFFFFFFF),
                                  child: CircleAvatar(
                                    radius: 75,
                                    backgroundImage: profilePicture
                                        ? NetworkImage(_imageUrl)
                                        : AssetImage(_imageUrl),
                                  ),
                                ),
                              ),
                            // More code...


我做错了什么?为什么我的图片没有更新?

已更新:


我试过了,所以我可以将图片的字节保存在 pictureTemp 中,调用 setState 重建小部件并将图片放入 Image.memory(pictureTemp)。但是好像不行。

  Uint8List pictureTemp;
  io.File profilePic;
  Future getFromCamara() async {
    var pickedFile = await ImagePicker().getImage(source: ImageSource.camera);
    var image = await pickedFile.readAsBytes();

    FirebaseStorage.instance
        .ref()
        .child('picture')
        .putFile(io.File(pickedFile.path));

    setState(() {
      pictureTemp = image;
    });
child: CircleAvatar(
          radius: 75,
          backgroundImage: profilePicture
               ? pictureTemp == null
                 ? AssetImage(_imageUrl)
                 : Image.memory(pictureTemp)
               : AssetImage(_imageUrl),
       ),

这里选择图片的时候直接设置也可以等firebase上传成功后再设置

但不是在上传后从 Firebase URL 加载图像,您可以直接从选择的文件 加载,如下所示;

image = Image.memory(await pickedFile.readAsBytes())

这将立即设置图像并将节省您对 Firebase 的读取调用。您应该始终尽可能减少 Firebase 读取。