expo-image-picker gives network request failed when i upload an image in ios but it works fine on android

Viewed 828

This is the code that i used to upload images on IOS

  let result = await ImagePicker.launchImageLibraryAsync({
                    mediaTypes: ImagePicker.MediaTypeOptions.Image,
                    allowsEditing: true,
                    quality: 1,
                });

And in the output i got,

Object {
  "cancelled": false,
  "height": 2001,
  "type": "image",
  "uri": "file:///Users/sajid/Library/Developer/CoreSimulator/Devices/A48F2141-D9AF-457A-9D14-D2F2D4B6336B/data/Containers/Data/Application/803F58D8-0CF9-43CA-8972-599C460687B1/Library/Caches/ExponentExperienceData/%2540sajid_542%252FGoTrillo/ImagePicker/19952322-2D5E-495B-A4AF-427EA23663A6.jpg",
  "width": 3000,
}

Till this point it works fine, later when i call fetch on result.uri, it gives me following error on ios ,

const response = await fetch(result.uri);

Output Error: TypeError: Network request failed

This Error is not beinng raise on Android where as in IOS its giving this error when i use the above functions for the second time.Someone please sugggest a fix for this issue.

4 Answers

There is an another workaround for this problem while Expo Team handles patching the react native version. For iOS you can use this implementation and for android regular XHR would be sufficient, detailed issue here.

I had the same issue for a long time. This is what I did.

Make sure you follow the amplify guide for setting up a app. amplify init, amplify add auth, amplify push, and then amplify add storage and then do this.

import Amplify, { Storage } from 'aws-amplify'
import config from './src/aws-exports'
// import awsconfig from './aws-exports';
// Might need to switch line 7 to awsconfig 
Amplify.configure(config)

import { StatusBar } from 'expo-status-bar';
import React, { useState, useEffect } from 'react';
import { Button, Image, View, Platform, StyleSheet, Text, TextInput } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

function App() {
  const [image, setImage] = useState(null)
  const [name, setName] = useState('Evan Erickson')

  useEffect(() => {
    (async () => {
      if (Platform.OS !== 'web') {
        const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
        if (status !== 'granted') {
          alert('Sorry, we need camera roll permissions to make this work!');
        }
      }
    })();
  }, []);

  const pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });
    
    console.log(result) 

    async function pathToImageFile(data) {
      try {
        const response = await fetch(data);
        const blob = await response.blob();
        await Storage.put(`customers/${name}`, blob, {
          contentType: 'image/jpeg', // contentType is optional
        });
      } catch (err) {
        console.log('Error uploading file:', err);
      }
    }
    // later
    pathToImageFile(result.uri);
  }

  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 }} />}
      <Button title="Upload image" onPress={() => {alert(image)}} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default withAuthenticator(App)

Here is the another way using which u can solve this problem and its work for me as well. https://github.com/expo/expo/issues/10394#issuecomment-700509863

import * as FileSystem from 'expo-file-system';
import * as firebase from 'firebase/app';
import * as ImagePicker from 'expo-image-picker';

// Pick the photo
const pickerResult = await ImagePicker.launchImageLibraryAsync({
    allowsEditing: true,
    aspect: [1, 1]
});

// Fetch the photo with it's local URI
const file = await FileSystem.readAsStringAsync(pickerResult.uri, {
    encoding: FileSystem.EncodingType.Base64,
});

// Create a ref in Firebase (I'm using my user's ID)
const ref = firebase.storage().ref().child(`avatars/${user.uid}`);

// Upload Base64 image to Firebase
const snapshot = await ref.putString(file, 'base64');

// Create a download URL
const remoteURL = await snapshot.ref.getDownloadURL();

// Return the URL
return remoteURL;
Related