Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Network request failed on react native upload image

I am trying to capture, and upload an image to a server from react native, however I get the following error when I make the http request:

[TypeError: Network request failed]

Here is my code, I have followed this tutorial:

https://heartbeat.fritz.ai/how-to-upload-images-in-a-react-native-app-4cca03ded855

import React from 'react';
import {View, Image, Button} from 'react-native';
import ImagePicker from 'react-native-image-picker';

export default class App extends React.Component {
  state = {
    photo: null,
  };

  createFormData = (photo) => {
    const data = new FormData();

    data.append('photo', {
      name: photo.fileName,
      type: photo.type,
      uri:
        Platform.OS === 'android'
          ? photo.uri
          : photo.uri.replace('file://', ''),
    });

    data.append('id', 1);
    return data;
  };

  handleChoosePhoto = () => {
    const options = {
      noData: true,
    };
    ImagePicker.launchImageLibrary(options, (response) => {
      if (response.uri) {
        this.setState({photo: response});
      }
    });
  };

  handleUploadPhoto = () => {
    fetch('http://192.168.1.104:3000/', {
      method: 'POST',
      body: this.createFormData(this.state.photo),
    })
      .then((response) => response.text())
      .then((response) => {
        console.log('upload success', response);
      })
      .catch((error) => {
        console.log('upload error', error);
      });
  };

  render() {
    const {photo} = this.state;
    return (
      <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
        {photo && (
          <React.Fragment>
            <Image
              source={{uri: photo.uri}}
              style={{width: 300, height: 300}}
            />
            <Button title="Upload" onPress={this.handleUploadPhoto} />
          </React.Fragment>
        )}
        <Button title="Choose Photo" onPress={this.handleChoosePhoto} />
      </View>
    );
  }
}

I've tried:

  • Add "Content: multipart/form-data" to http request headers
  • Add Accept: Accept: application/json" to http request headers

I have noticed that the request fails, only when I add the photo object to the "FormData", that is, the http request runs correctly when I remove the following code:

data.append('photo', {
      name: photo.fileName,
      type: photo.type,
      uri:
        Platform.OS === 'android'
          ? photo.uri
          : photo.uri.replace('file://', ''),
    });

Edit 02-07-2020

I finally found the solution here:

https://github.com/facebook/react-native/issues/28551#issuecomment-610652110

like image 812
Juan Diego Cardona Marin Avatar asked Oct 16 '22 02:10

Juan Diego Cardona Marin


2 Answers

The first issue is with the imageUri itself. If let’s say photo path is /user/.../path/to/file.jpg. Then file picker in android would give imageUri value as file:/user/.../path/to/file.jpg whereas file picker in iOS would give imageUri value as file:///user/.../path/to/file.jpg.

The solution for the first issue is to use file:// instead of file: in the formData in android.

The second issue is that we are not using proper mime-type. It is working fine on iOS but not on Android. What makes this worse is that the file-picker package gives the type of the file as “image” and it does not give proper mime-type.

The solution is to use proper mime-type in the formData in the field type. Ex: mime-type for .jpg file would be image/jpeg and for .png file would be image/png. We do not have to do this manually. Instead, you can use a very famous npm package called mime.

import mime from "mime";

const newImageUri =  "file:///" + imageUri.split("file:/").join("");

const formData = new FormData();
formData.append('image', {
 uri : newImageUri,
 type: mime.getType(newImageUri),
 name: newImageUri.split("/").pop()
}); 
like image 171
Anthony phillips Avatar answered Nov 03 '22 00:11

Anthony phillips


This solution also works:

I had same this issue in my project with react-native version 0.62. I updated flipper to "0.41.0" and it worked.

In gradle.properities

FLIPPER_VERSION=0.41.0

gradle.properties is located at PROJECT_ROOT/android

like image 43
glinda93 Avatar answered Nov 03 '22 01:11

glinda93