I am using Axios and React Native Expo. I am getting the image from the user using the expo-image-picker library. I want to get images from my users and upload them to Cloudflare images how can I do that? I have also tried uploading Digital Ocean Spaces but that too gives similar errors. I want a image hosting service that works with my expo app. Cloudinairy is very expensive.
I have tried the official docs but am running into errors, here is the code I used-
<code>import { View, Text, TextInput, Alert, TouchableOpacity, Image } from 'react-native';
import React, { useState, useEffect } from 'react';
import { SafeAreaView } from 'react-native-safe-area-context';
import * as Icon from 'react-native-feather';
import { themeColors } from '../theme';
import AsyncStorage from '@react-native-async-storage/async-storage';
import axios from 'axios';
import * as ImagePicker from 'expo-image-picker';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
import 'react-native-url-polyfill/auto';
import { ReadableStream } from 'web-streams-polyfill';
globalThis.ReadableStream = ReadableStream;
// Replace these with your actual Cloudflare account details
const CLOUDFLARE_ACCOUNT_ID = '';
const CLOUDFLARE_API_TOKEN = '';
export default function AddItems({ navigation }) {
const [produceName, setProduceName] = useState('');
const [quantity, setQuantity] = useState('');
const [price, setPrice] = useState('');
const [itemImage, setItemImage] = useState('');
const [phoneNumber, setPhoneNumber] = useState('');
const [uploading, setUploading] = useState(false);
useEffect(() => {
const loadPhoneNumber = async () => {
try {
const storedPhoneNumber = await AsyncStorage.getItem('phone');
if (storedPhoneNumber) {
setPhoneNumber(storedPhoneNumber);
} else {
Alert.alert('Error', 'Phone number not found');
}
} catch (error) {
console.error('Error loading phone number from AsyncStorage:', error);
}
};
loadPhoneNumber();
}, []);
const pickImageAsync = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
quality: 1,
});
if (!result.canceled) {
uploadImage(result.assets[0]);
} else {
alert('You did not select any image.');
}
};
const getImageBlob = async (uri) => {
const response = await fetch(uri);
const blob = await response.blob();
return blob;
};
const uploadImage = async (imageAsset) => {
setUploading(true);
const customPath = `${uuidv4()}-${produceName.replace(/s+/g, '-').toLowerCase()}`;
try {
const blob = await getImageBlob(imageAsset.uri);
const formData = new FormData();
formData.append('file', blob, 'image.jpg');
formData.append('id', customPath);
console.log('Uploading to Cloudflare...');
console.log('FormData:', JSON.stringify(formData));
const response = await axios.post(
`https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/images/v1`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': `Bearer ${CLOUDFLARE_API_TOKEN}`,
},
timeout: 30000, // Increased timeout to 30 seconds
}
);
console.log('Cloudflare response:', response.data);
if (response.data.success) {
const imageUrl = response.data.result.variants[0];
setItemImage(imageUrl);
Alert.alert('Success', 'Image uploaded successfully');
} else {
throw new Error('Upload failed: ' + JSON.stringify(response.data.errors));
}
} catch (error) {
console.error('Error uploading image:', error);
if (error.response) {
console.error('Error data:', error.response.data);
console.error('Error status:', error.response.status);
console.error('Error headers:', error.response.headers);
} else if (error.request) {
console.error('Error request:', error.request);
} else {
console.error('Error message:', error.message);
}
Alert.alert('Error', `Failed to upload image: ${error.message}`);
} finally {
setUploading(false);
}
};
const handleSubmit = async () => {
if (!produceName || !quantity || !price) {
Alert.alert('Error', 'All fields are required');
return;
}
try {
const formData = {
phoneNumber,
itemName: produceName,
quantity,
price,
itemImage,
};
const response = await axios.post(
'myurl/api/supplier/add-item',
formData
);
if (response.status === 200) {
Alert.alert('Success', 'Item added successfully!');
navigation.goBack();
}
} catch (error) {
console.error('Error adding item:', error.response?.data || error.message);
Alert.alert(
'Error',
error.response?.data?.message || 'Failed to add item, please try again'
);
}
};
return (
//frontend code
);
}
</code>
<code>import { View, Text, TextInput, Alert, TouchableOpacity, Image } from 'react-native';
import React, { useState, useEffect } from 'react';
import { SafeAreaView } from 'react-native-safe-area-context';
import * as Icon from 'react-native-feather';
import { themeColors } from '../theme';
import AsyncStorage from '@react-native-async-storage/async-storage';
import axios from 'axios';
import * as ImagePicker from 'expo-image-picker';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
import 'react-native-url-polyfill/auto';
import { ReadableStream } from 'web-streams-polyfill';
globalThis.ReadableStream = ReadableStream;
// Replace these with your actual Cloudflare account details
const CLOUDFLARE_ACCOUNT_ID = '';
const CLOUDFLARE_API_TOKEN = '';
export default function AddItems({ navigation }) {
const [produceName, setProduceName] = useState('');
const [quantity, setQuantity] = useState('');
const [price, setPrice] = useState('');
const [itemImage, setItemImage] = useState('');
const [phoneNumber, setPhoneNumber] = useState('');
const [uploading, setUploading] = useState(false);
useEffect(() => {
const loadPhoneNumber = async () => {
try {
const storedPhoneNumber = await AsyncStorage.getItem('phone');
if (storedPhoneNumber) {
setPhoneNumber(storedPhoneNumber);
} else {
Alert.alert('Error', 'Phone number not found');
}
} catch (error) {
console.error('Error loading phone number from AsyncStorage:', error);
}
};
loadPhoneNumber();
}, []);
const pickImageAsync = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
quality: 1,
});
if (!result.canceled) {
uploadImage(result.assets[0]);
} else {
alert('You did not select any image.');
}
};
const getImageBlob = async (uri) => {
const response = await fetch(uri);
const blob = await response.blob();
return blob;
};
const uploadImage = async (imageAsset) => {
setUploading(true);
const customPath = `${uuidv4()}-${produceName.replace(/s+/g, '-').toLowerCase()}`;
try {
const blob = await getImageBlob(imageAsset.uri);
const formData = new FormData();
formData.append('file', blob, 'image.jpg');
formData.append('id', customPath);
console.log('Uploading to Cloudflare...');
console.log('FormData:', JSON.stringify(formData));
const response = await axios.post(
`https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/images/v1`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': `Bearer ${CLOUDFLARE_API_TOKEN}`,
},
timeout: 30000, // Increased timeout to 30 seconds
}
);
console.log('Cloudflare response:', response.data);
if (response.data.success) {
const imageUrl = response.data.result.variants[0];
setItemImage(imageUrl);
Alert.alert('Success', 'Image uploaded successfully');
} else {
throw new Error('Upload failed: ' + JSON.stringify(response.data.errors));
}
} catch (error) {
console.error('Error uploading image:', error);
if (error.response) {
console.error('Error data:', error.response.data);
console.error('Error status:', error.response.status);
console.error('Error headers:', error.response.headers);
} else if (error.request) {
console.error('Error request:', error.request);
} else {
console.error('Error message:', error.message);
}
Alert.alert('Error', `Failed to upload image: ${error.message}`);
} finally {
setUploading(false);
}
};
const handleSubmit = async () => {
if (!produceName || !quantity || !price) {
Alert.alert('Error', 'All fields are required');
return;
}
try {
const formData = {
phoneNumber,
itemName: produceName,
quantity,
price,
itemImage,
};
const response = await axios.post(
'myurl/api/supplier/add-item',
formData
);
if (response.status === 200) {
Alert.alert('Success', 'Item added successfully!');
navigation.goBack();
}
} catch (error) {
console.error('Error adding item:', error.response?.data || error.message);
Alert.alert(
'Error',
error.response?.data?.message || 'Failed to add item, please try again'
);
}
};
return (
//frontend code
);
}
</code>
import { View, Text, TextInput, Alert, TouchableOpacity, Image } from 'react-native';
import React, { useState, useEffect } from 'react';
import { SafeAreaView } from 'react-native-safe-area-context';
import * as Icon from 'react-native-feather';
import { themeColors } from '../theme';
import AsyncStorage from '@react-native-async-storage/async-storage';
import axios from 'axios';
import * as ImagePicker from 'expo-image-picker';
import 'react-native-get-random-values';
import { v4 as uuidv4 } from 'uuid';
import 'react-native-url-polyfill/auto';
import { ReadableStream } from 'web-streams-polyfill';
globalThis.ReadableStream = ReadableStream;
// Replace these with your actual Cloudflare account details
const CLOUDFLARE_ACCOUNT_ID = '';
const CLOUDFLARE_API_TOKEN = '';
export default function AddItems({ navigation }) {
const [produceName, setProduceName] = useState('');
const [quantity, setQuantity] = useState('');
const [price, setPrice] = useState('');
const [itemImage, setItemImage] = useState('');
const [phoneNumber, setPhoneNumber] = useState('');
const [uploading, setUploading] = useState(false);
useEffect(() => {
const loadPhoneNumber = async () => {
try {
const storedPhoneNumber = await AsyncStorage.getItem('phone');
if (storedPhoneNumber) {
setPhoneNumber(storedPhoneNumber);
} else {
Alert.alert('Error', 'Phone number not found');
}
} catch (error) {
console.error('Error loading phone number from AsyncStorage:', error);
}
};
loadPhoneNumber();
}, []);
const pickImageAsync = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
quality: 1,
});
if (!result.canceled) {
uploadImage(result.assets[0]);
} else {
alert('You did not select any image.');
}
};
const getImageBlob = async (uri) => {
const response = await fetch(uri);
const blob = await response.blob();
return blob;
};
const uploadImage = async (imageAsset) => {
setUploading(true);
const customPath = `${uuidv4()}-${produceName.replace(/s+/g, '-').toLowerCase()}`;
try {
const blob = await getImageBlob(imageAsset.uri);
const formData = new FormData();
formData.append('file', blob, 'image.jpg');
formData.append('id', customPath);
console.log('Uploading to Cloudflare...');
console.log('FormData:', JSON.stringify(formData));
const response = await axios.post(
`https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/images/v1`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': `Bearer ${CLOUDFLARE_API_TOKEN}`,
},
timeout: 30000, // Increased timeout to 30 seconds
}
);
console.log('Cloudflare response:', response.data);
if (response.data.success) {
const imageUrl = response.data.result.variants[0];
setItemImage(imageUrl);
Alert.alert('Success', 'Image uploaded successfully');
} else {
throw new Error('Upload failed: ' + JSON.stringify(response.data.errors));
}
} catch (error) {
console.error('Error uploading image:', error);
if (error.response) {
console.error('Error data:', error.response.data);
console.error('Error status:', error.response.status);
console.error('Error headers:', error.response.headers);
} else if (error.request) {
console.error('Error request:', error.request);
} else {
console.error('Error message:', error.message);
}
Alert.alert('Error', `Failed to upload image: ${error.message}`);
} finally {
setUploading(false);
}
};
const handleSubmit = async () => {
if (!produceName || !quantity || !price) {
Alert.alert('Error', 'All fields are required');
return;
}
try {
const formData = {
phoneNumber,
itemName: produceName,
quantity,
price,
itemImage,
};
const response = await axios.post(
'myurl/api/supplier/add-item',
formData
);
if (response.status === 200) {
Alert.alert('Success', 'Item added successfully!');
navigation.goBack();
}
} catch (error) {
console.error('Error adding item:', error.response?.data || error.message);
Alert.alert(
'Error',
error.response?.data?.message || 'Failed to add item, please try again'
);
}
};
return (
//frontend code
);
}