Javier Heisecke
Javier Heisecke

Reputation: 1212

App showing wrong File, after converting base64 to File

I'm trying to convert a Uint8List to a File.

TL;DR: My backend sends me a base64 String, and I'm trying to show that in my app.

What's the problem?

  1. I first see my profile picture
  2. I change my profile picture and send it to my backend which gets the new profile pictures and saves it
  3. I reload the screen and the old profile picture is shown, whe I debug and check the base64 String sent by my backend I can see I'm receiving the new profile picture, even though the old is shown
  4. To see my changes I restart the app manually

enter image description here

About the code

    File _storedImage;
    Future _initialImage;
    final imagePicker = ImagePicker();
    
    @override
    void initState() {
      _initialImage = _initiateStoredImage();
      super.initState();
    }
    
    Future _initiateStoredImage() async {
      Uint8List bytes = base64Decode(widget.profilePicture);
    
      final tempPath = await syspaths.getTemporaryDirectory();
    
      _storedImage = File('${tempPath.path}/profile.png');
      await _storedImage.writeAsBytes(
          bytes.buffer.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes));
    }

I use this method to store the image

Future _getImage(bool fromCamera) async {
    final ImagePicker picker = ImagePicker();
    final pickedFile = await picker.getImage(
        source: fromCamera ? ImageSource.camera : ImageSource.gallery);
    File imageFile;
    if (pickedFile != null) {
      imageFile = File(pickedFile.path);
    } else {
      return;
    }
    setState(() {
      if (pickedFile != null) {
        _storedImage = imageFile;
      }
    });
    final tempPath = await syspaths.getTemporaryDirectory();
    final savedImage = await imageFile.copy('${tempPath.path}/profile.png');
    widget.onSelectImage(savedImage);
  }

To render the image I use this widget

FutureBuilder(
  future: _initialImage,
  builder: (_, dataSnapshot) {
    if (dataSnapshot.connectionState ==
        ConnectionState.waiting) {
      return Center(child: CircularProgressIndicator());
    } else {
      if (dataSnapshot.error != null) {
        return Center(
          child: Text('Algo salio mal'),
        );
      } else {
        return Container(
          width: 150.0,
          height: 150.0,
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            image: DecorationImage(
                image: _storedImage != null
                    ? FileImage(_storedImage)
                    : AssetImage(
                        "assets/images/default-avatar.png"),
                fit: BoxFit.cover,
                alignment: Alignment.center),
          ),
        );
      }
    }
  },
),

Upvotes: 1

Views: 70

Answers (1)

jamesdlin
jamesdlin

Reputation: 89946

Flutter's ImageCache caches FileImages based on file path. If you're overwriting the original file, the path won't change, so Flutter will continue drawing the cached image. In that case, you will need to call the evict method first to remove the cached version.

Upvotes: 1

Related Questions