1

I want users to be able to pick a profile picture from the gallery using the Image Picker from expo and upload it to supabase in a filename that is structured like this userid.jpeg. I then want to access this file and get its url to display the image when i need it. The issue is that a file is being uploaded to supabase but its either 0 bytes or doesn't contain anything. Could somebody please help me i am a beginner.

Here is my code for context: Pick image from gallery code:

 const pickImage = async () => {
        let result = await ImagePicker.launchImageLibraryAsync({
          mediaTypes: ImagePicker.MediaTypeOptions.Images,
          allowsEditing: false,
          aspect: [4, 3],
          quality: 0.7,
        });
      
        if (!result.canceled) {
          // Access the selected asset from the assets array
          const selectedAsset = result.assets[0];
          setProfileImage(selectedAsset.uri);
        }
          };

Uploading to supabase storage code:

        try {
        console.log("Starting upload...");
          const sanitizedId = sanitizeFilename(userId); // Sanitize the user id
          const filename = `${sanitizedId}.jpeg`; // Assuming you want to save as jpeg
    
          // Convert the file URI to blob
          const blob = await fetch(imageUri).then((res) => res.blob());
          console.log("Uploading blob...");
          const { error } = await supabase
            .storage
            .from('profile-pictures')
            .upload(filename, blob, {
              cacheControl: '3600',
              contentType: 'image/jpeg', // Specify the content type
              upsert: false
            });
    
          if (error) {
            console.error('Error uploading profile picture:', error);
            return null;
          }
          console.log("Getting public URL...");
          const { data } = await supabase
            .storage
            .from('profile-pictures')
            .getPublicUrl(filename);
    
          console.log('Profile picture URL:', data);
          return data;
        } catch (error) {
          console.error('Error in uploadProfilePictureToSupabase:', error);
          return null;
        }
      };
      const sanitizeFilename = (filename) => {
        return filename.replace(/[^\w.-]/g, ''); // Replace invalid characters
      
      };```



I tried using blobs but i got even more confused.

1 Answer 1

7

According to the Supabase documentation

"For React Native, using either Blob, File or FormData does not work as intended. Upload file using ArrayBuffer from base64 file data instead, see example below."

import { decode } from 'base64-arraybuffer';

const { data, error } = await supabase
  .storage
  .from('avatars')
  .upload('public/avatar1.png', decode('base64FileData'), {
    contentType: 'image/png'
})

base64-arraybuffer library

To get the base64 string you use:

let result = await ImagePicker.launchImageLibraryAsync({
   mediaTypes: ImagePicker.MediaTypeOptions.Images,
   allowsEditing: false,
   aspect: [4, 3],
   quality: 0.7,
   base64: true, //Add this line
});
1
  • This worked well. Thank you.
    – haris
    Commented Oct 7, 2024 at 3:27

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.