Update: It turns out I was forgetting to specify the contentType in the fileOptions argument of the Supabase upload function.
For the contentType the Supabase docs say:
Should be specified if using a
fileBodythat is neitherBlobnorFilenorFormData, otherwise will default totext/plain;charset=UTF-8.
In Supabase bucket upload:
let {data : bucket_file, error: upload_error} = await supabase.storage
.from('avatars')
.upload(filePath, decode(image.base64), {
contentType: photo.type,
upsert: true
})