supabase/storage-js

Downloaded file after from.upload() upsert is always the same. Error replacing file.

bennik88 opened this issue · 4 comments

Bug report

Describe the bug

I'm downloading an image file with .from(bucket).download(path) after replacing the image with .from("avatars").upload(filePath, file, { upsert: true }); but the downloaded file is always the same. Only if I delete it and upload a new one it's downloading the newly uploaded file.

To Reproduce

  1. Upload an image with:
  const { data, error } = await supabase.storage
    .from("avatars")
    .upload("user1/user1_avatarImage.jpeg", file, {
      upsert: true,
    });
  1. Download the image with:
const { data, error } = await supabase.storage.from("avatars").download("user1/user1_avatarImage.jpeg");
  1. The image is the uploaded one and looks good. Now replace the image in the next step.

  2. Upload a new image under same name and same path:

  const { data, error } = await supabase.storage
    .from("avatars")
    .upload("user1/user1_avatarImage.jpeg", newFile, {
      upsert: true,
    });
  1. Go to Supabase dashboard and press refresh. Image is still the same and wasn't replaced (first issue). Refresh the browser window. Image has now changed and you'll thee the new uploaded image.
  2. Download the image with:
const { data, error } = await supabase.storage.from("avatars").download("user1/user1_avatarImage.jpeg");

The image is still the old one and won't show the new one. The from().download() function won't return the new image on storage.

Expected behavior

from().download() always returning the newest storage file.

System information

  • OS: [macOS]
  • Browser [chrome]
  • Version of supabase-js: [^2.0.0-rc.10]

This is likely do to caching in the browser/cdn.
supabase/supabase#5743
Did not test this again, but I seem to have found a cache busting string works in download...

I have read my way through your linked issue but couldn’t find and understand what to do about it? What do you mean by “cache busting string works in download”? Can i Force delete the cache when downloading? And if yes how in my example?

This was the issue I submitted: supabase/storage#116
const { data, error } = await supabase.storage.from("avatars").download("user1/user1_avatarImage.jpeg" + '?bust='+Date.now())
Not tested right now, but looks right...
This should only be used when you need to see a copy of what you just replaced. You do not want to do this on an app for normal downloads as it will stop any caching from occurring.

Thank you @GaryAustin1 for why this issue is currently happening!
I looked at your param when using the download() function and indeed it shows the new image when using a suffix '?bust='+Date.now()).
The issue here why I think this won't work in practical situations is, that I'm for example having an avatar_url column in my profiles table which is the path to the avatar image and when the page refreshes or the user logs in it takes that URL and downloads the image. So that means that when he uploads a new avatar image that would replace the old photo in the storage for that I pass a parameter to my superbaseDownloadImage(burstCDNAvatarCache = true) which appends the key and value, and he gets the new photo back. But imagine he refreshes the page, which would take the avatar_url and download it without burstCDNAvatarCache set to true as he hasn't uploaded/ replaced an avatar photo (so wouldn't make sense to set it to true) he would again suddenly see his old photo. So I would need to store the DateTime of his burst anywhere and let it go after let's say an hour. Which seems horrible (especially when doing this for every photo that is going to be replaced). Or am I missing something?
Could it be easier to just write a trigger function that realizes the upload and removes the file before uploading it? So I wouldn't have any CDN Cache issues.
I hope the Supabase Team fixes this. It seems quite off at the moment. I don't know how firebase solved it in the background but they for example returned the newest photo but also used CNDs for my knowledge. Same when using Google Cloud Buckets. What do you think?