Sharki
Sharki

Reputation: 424

flutter, trying to update a picture from Storage

I'm trying to upload, and update a picture from firebase storage. But for some reason this is not working properly.

This would be the scenario; A user take a picture from his camera, so this picture is uploaded to my storage, so after that I get the url picture, so I can use this like NetworkImage(url) to update the picture.

This is what's happening currently:


Let's say I don't have any picture.

Now let's say I want to update my profile picture, so I take another picture, let's call it A so I upload this one.

But If I try again with a B picture, for some reason the picture is updated with the A picture.


This would be my code and how I'm facing this feature.

I have the next method which is invoked when a user click over his picture. I wait for the result (value) so when I got the result I upload the picture. Then, when the picture is uploaded, I just call to setState and save the url into the _imageUrl variable.

After that, I change the "profilePic" attribute from my data base to 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());
    }

So now, using a StreamBuilder, I get the result of profilePic from my DataBase, if is True, I download the URL, and if don't, I just use the Asset default's pic.

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


What I'm doing wrong? Why my picture isn't getting updated?

Updated:


I tried this, so I can save in pictureTemp the picture's bytes, calling to setState to rebuild the widget and put the picture with Image.memory(pictureTemp). But it doesn't seem to work.

  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),
       ),

Upvotes: 1

Views: 1856

Answers (1)

Akshar Patel
Akshar Patel

Reputation: 9378

Here when the image is picked you should directly set it or you can set it after the firebase upload is finished successfully.

But rather than loading an image from Firebase URL after the upload, you can directly load from the picked file as follows;

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

This will instantly set the image and will save you a read call to Firebase. You should always try to minimize the Firebase Reads whenever possible.

Upvotes: 1

Related Questions