supabase/storage-js

The image uploaded to Storage is stored as a blank image of 0 bytes.

dog6o opened this issue ยท 6 comments

dog6o commented

Bug report

The image uploaded to Storage is stored as a blank image of 0 bytes.

Describe the bug

When an image file opened with type="file" input is processed by Resize and Cover in the image manipulation library before being uploaded to Storage, and then the processed image data is uploaded to Storage, it is uploaded as a 0-byte image with nothing displayed. If the processed image data is uploaded to Storage, it is uploaded as a 0-byte image with nothing displayed.
A clear and concise description of what the bug is.

To Reproduce

I tested with Jimp, compressorjs, and various other image manipulation libraries that can resize images while maintaining aspect ratio, and was able to reproduce the problem where all resized images are uploaded as 0-byte images when uploaded.

Steps to reproduce the behavior, please provide code snippets or a repository:

const uploadAvatar = async () => {
  try {
    uploading = true;

    if (!files || files.length === 0) {
      throw new Error('You must select an image to upload.');
    }

    const file = files[0];
    const fileExt = file.name.split('.').pop();
    const fileName = `${Math.random()}.${fileExt}`;
    const filePath = `${fileName}`;
    const fileType = file.type;

    let arrayBuffer;
    jimp.read(await files[0].arrayBuffer(), (err, lenna) => {
      if (err) throw err;
      lenna.getBuffer(fileType, (err, buf) => {
        if (err) throw err;
        arrayBuffer = buf;
      });
    });

    const { error: uploadError } = await supabase.storage
      .from('avatars')
      .upload(filePath, arrayBuffer, {
        contentType: fileType,
      });

    if (uploadError) throw uploadError;

    path = filePath;
    dispatch('upload');
  } catch (error) {
    alert(error.message);
  } finally {
    uploading = false;
  }
};

Expected behavior

The image data resized by the image manipulation library is successfully uploaded to Storage.

Screenshots

https://imgur.com/bZ9ZntV

System information

Windows 11 Pro 22622.290
supabase-js 1.35.4
node.js 18.3.0

Additional context

Add any other context about the problem here.

@supabase/storage-team
Assigning the PIC of the Storage team to take care of this.

Hey @MyAlfisti! This isn't an issue with storage-js. In your code, the resized array buffer will only be available asynchronously in the callback, but you are immediately executing the storage.from().upload() function, hence at the time of execution, the arrayBuffer will not be defined and hence will be uploaded as a 0-byte file. You will need to wait for the image buffer to be available before triggering the upload.

fenos commented

As @bnjmnt4n mentioned, your problem is that you are not waiting for the arrayBuffer to be set before uploading the file

I'm facing the same issue, but I'm using a File object instead of an arrayBuffer (on React Native) - do I need to use an arrayBuffer or is there something else wrong?

I'm facing the same issue, but I'm using a File object instead of an arrayBuffer (on React Native) - do I need to use an arrayBuffer or is there something else wrong?

Same issue here, whenever I try to upload any image they are all blank/empty. Did you find any solution ? ๐Ÿ™๐Ÿผ Thanks

For anyone who is still experiencing this try to upload the image as a buffer

const buffer = Buffer.from(base64String, 'base64');

And add the contentType while uploading

const {data, error} = await supabase.storage
    .from('avatars')
    .upload(name, buffer, {
      cacheControl: '3600',
      upsert: false,
      contentType: 'image/jpg', // <- HERE
    });

For me that worked