Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple issues for changed image behind unchanged URL, e.g. profile pictures / user avatars #897

Open
ltOgt opened this issue Dec 4, 2023 · 1 comment

Comments

@ltOgt
Copy link

ltOgt commented Dec 4, 2023

There are quite a few issues about the use case of changing images behind an identical URL.

E.g. user profile pictures that have been changed by the user.

The main issue here is that ImageProvider.resolveStreamForKey only calls ImageProvider.loadImage through ImageCache.putIfAbsent.

This means that all the good caching logic with if-none-match etc is only called once during the apps lifetime, when the URL is used for the first time and is not yet registered in ImageCache.

The quick solution here is to manually call

PaintingBinding.instance.imageCache.evict(CachedNetworkImageProvider(url), includeLive: true)

iff you know the exact url, or

PaintingBinding.instance.imageCache.clearLiveImages();
PaintingBinding.instance.imageCache.clear();

to brute-force clear the entire cache to force a refresh.


The package already exposes CachedNetworkImage.evictFromCache(url), but this removes the on disk cache as well, meaning we don't get to use the old image while loading the new one, or checking with etag in case the resource has not changed after all.

It might be good to expose something like CachedNetworkImage.forceRefresh(url).


P.S. see https://github.com/ltOgt/flutter_cached_network_image_404 for a minimal example of this

@mark8044
Copy link

mark8044 commented Dec 9, 2023

This makes alot of sense.

I was wondering if you had any thoughts on something else, more along the image 404 lines: Baseflow/flutter_cache_manager#439

Your PR Baseflow/flutter_cache_manager#437 didn't work for my use case, but wondering if you had any ideas on my above specific problem?

In a nutshell, when an image does not exist AND the maxWidth/maxHeight are set I believe the stream never closes. This becomes a problem because a) there is a leak and b) the subsequent attempts to load that image already have an open stream and no more errors are thrown.

This is just a guess, but what im seeing happening is:

  1. Open widget with CachedNetworkImageProvider and use maxWidth parameter
  2. Proper exception is thrown that the image does not exist. I can then inside by FutureBuilder present my own 404 error widget
  3. Close the widget altogeter
  4. Reload the same widget
  5. This time no error is thrown, and FutureBuilder stays on ConnectionStatus.waiting forever.

To note, if you remove maxWidth/maxHeight then this problem does not happen

Again, I think its because the stream never closed or listener was never removed from the first failure and because it thinks the 404 .html page is sitting in the memory cache, it doesn't need to mess with that anymore.

I've tried to evict the image and delete it from the file store (using my custom image cache) when the first catchable error happens. It does delete from the file store successfully (I see the .html file go away), but I think it stays in the memory cache, as the subsequent loads do not try to put it back into file store. Ive also tried the CachedNetworkImage.evictFromCache(url) it as far as I can tell it doesn't affect this problem either

I posted the problem in cache_manager, because Im wondering if the problem is on that side of the process, but you seem to be the only one tackling this 404 image problems.

From my own messing around, I think the problem is here: https://github.com/Baseflow/flutter_cached_network_image/blob/develop/cached_network_image/lib/src/image_provider/_image_loader.dart#L129C12-L129C47

But can't figure out how that relates to getting stuck with the image stream open or the image sitting in memory (the 404 webpage that is)

Was hoping you had some ideas or this relates to your PRs. Im going to try this one out now and see if it does anything here.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants