Question

How to upload images to Digital Ocean spaces bucket using Expo and AWS sdk

I am trying to upload an image to my DigitalOcean Spaces using the Expo Image Picker and AWS SDK, but I keep encountering this error:

ERROR  Error uploading image: [TypeError: Network request failed]

Here’s the relevant code that I’m using to upload the image:

import axios from 'axios';
import * as ImagePicker from 'expo-image-picker';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import 'react-native-get-random-values'; // This polyfills crypto.getRandomValues
import { v4 as uuidv4 } from 'uuid';
import { spaces } from '../config/digitalOcean';
import 'react-native-url-polyfill/auto';
import { ReadableStream } from 'web-streams-polyfill';
globalThis.ReadableStream = ReadableStream;


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);

  const s3Client = new S3Client({
    endpoint: spaces.url,
    forcePathStyle: false,
    region: "blr1",
    credentials: {
      accessKeyId: spaces.spacesKey,
      secretAccessKey: spaces.spacesSecret
    }
  });

  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 fileName = `${uuidv4()}.jpg`;

    try {
      const response = await fetch(imageAsset.uri);
      const blob = await getImageBlob(imageAsset.uri);
      console.log("these happened without error")
      console.log(response)
      console.log(blob)

      const params = {
        Bucket: spaces.name,
        Key: fileName,
        Body: blob,
        ACL: "public-read",
        ContentType: 'multipart/form-data',
      };

      const data = await s3Client.send(new PutObjectCommand(params));
      console.log(data)


      const imageUrl = spaces.url + "/" +  fileName
      setItemImage(imageUrl);
      Alert.alert('Success', 'Image uploaded successfully');
    } catch (error) {
      console.error('Error uploading image:', error);
      Alert.alert('Error', 'Failed to upload image');
    }
    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'
      );
    }
  };

Since it is a expo app, in the cors settings i have used “*” as the domain name and enabled all methods (get,put,post etc). It is still giving the network error.


Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Bobby Iliev
Site Moderator
Site Moderator badge
March 2, 2025

Hi there,

The Network request failed error usually indicates a CORS issue or an incorrect endpoint. But it could also be a problem with how Expo handles network requests.

On the endpoint side, DigitalOcean Spaces uses https://{SPACE_NAME}.{REGION}.digitaloceanspaces.com as the endpoint.

So your s3Client should have forcePathStyle: false and endpoint: 'https://blr1.digitaloceanspaces.com' (or your region).

On the CORS front, even if you’ve set "*" in CORS, double-check that it’s correctly applied in the Spaces settings under Manage Permissions → CORS.

As a quick test, try uploading an image using curl or Postman to verify if Spaces is responding correctly.

- Bobby

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.