I'm using expo, expo-image-picker, amplify with s3 to store images. Whenever I try to upload the image, that happens almost successfully - I see a new file on the bucket. But all of the files are 101-170 bytes size, so they don't have any real image behind that.
Though there's a new file created in s3 bucket, when I try to upload something, as well I get this error in my console.log:
ERROR [ERROR] 10:01.882 axios-http-handler - Request failed with status code 400 ERROR [ERROR] 10:01.922 AWSS3ProviderManagedUpload - Error happened while finishing the upload. ERROR [ERROR] 10:02.234 axios-http-handler - Request failed with status code 404 WARN Possible Unhandled Promise Rejection (id: 1): NoSuchUpload: The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.
I've tried many different approaches in order to fix that. I tried uploading the image from virtual android device, from real android device, from iPhone. Nothing works.
import React, { useState, useEffect } from 'react';
import { Button, Image, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import { v4 as uuidv4 } from 'uuid';
import { Storage } from 'aws-amplify';
export default function ImagePickerExample() {
const [image, setImage] = useState('');
useEffect(() => {
(async () => {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status !== 'granted') {
alert('Sorry, we need camera roll permissions to make this work!');
}
})();
}, []);
const pickImage = async () => {
try {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result);
if (!result.canceled) {
setImage(result.assets[0].uri);
}
} catch (error) {
console.log('Error picking an image:', error);
}
};
useEffect(() => {
const uploadImageToStorage = async () => {
try {
const response = await fetch(image);
const blob = await response.blob();
Storage.put(`${uuidv4()}.jpg`, blob);
console.log('Image uploaded successfully!');
} catch (error) {
console.log('Error uploading file:', error);
}
};
if (image) {
uploadImageToStorage();
}
}, [image]);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button title="Pick an image from camera roll" onPress={pickImage} />
{image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
</View>
);
}
I checked the CORS policy of my bucket to include EAT, I checked the aws-exports file has the actual bucket id in it, the region is correct as well. I tried to use many different options of imagePicker, tried almost every option in Storage.put.
So I found what was the error for me. It took almost 20 hours of search, but try this:
Make sure you work correctly with that assets[0].uri and so on. Due to the latest update of expo ImagePicker package, it's no longer result.uri, it's result.assets[0].uri
Good luck everyone!