I am using Expo Image Picker to select an image from the gallery so I can upload the file to a Supabase storage bucket called 'avatars'. In the Supabase storage docs they say:
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.
They also give this example:
import { decode } from 'base64-arraybuffer'
const { data, error } = await supabase
.storage
.from('avatars')
.upload('public/avatar1.png', decode('base64FileData'), {
contentType: 'image/png'
})
I thought to decode the base64 string of the Image Picker result and pass it in as Supabase's fileBody in upload.
In my code below I am getting the following error at the bucket uploading:
[StorageApiError: mime type text/plain;charset=UTF-8 is not supported]
async function uploadAvatar(){
try{
if (!session?.user) throw new Error("No user on the session!")
setUploading(true)
const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync()
if(!permissionResult.granted){
Alert.alert('Permission required', 'Permission to access the media library is required.');
return;
}
let result = await ImagePicker.launchImageLibraryAsync({
//Default mediaType is images
allowsEditing: true,
aspect: [4, 3],
quality: 1,
base64: true,
})
// console.log(result)
if(!result.canceled){
const image = result.assets[0]
const fileExt = image.fileName?.split('.').pop()
const filePath = `${session?.user?.id as string}/avatar.${fileExt}`
if(!image.base64){
throw new Error("Could not upload image.")
}
let {data : bucket_file, error: upload_error} = await supabase.storage
.from('avatars')
.upload(filePath, decode(image.base64), {upsert: true})
if(upload_error){
console.log(upload_error)
throw upload_error
}
const {data: profile, error: profile_error} = await supabase
.from("profiles")
.select("avatar_url")
.eq('user_id', session?.user?.id)
.single()
if(profile_error){
throw(profile_error)
}
if(!profile?.avatar_url){
const {error: update_error} = await supabase
.from("profiles")
.update({
avatar_url: bucket_file?.path,
updated_at: new Date(),
})
.eq('user_id', session?.user?.id)
if(update_error){
throw(update_error)
}
}
const { error: tsError } = await supabase
.from("profiles")
.update({
updated_at: new Date()
})
.eq("user_id", session?.user?.id);
if(tsError){
throw tsError
};
}
} catch(error){
if (error instanceof Error){
Alert.alert(error.message)
}
} finally {
setUploading(false)
}
}
I would very much appreciate your help, thank you!