0
votes

I am using react-native-image-picker to fetch image details and try to upload in https backend server. the request is not successful and it throws network error. It did not esablish the connection with the backend server. The problem is with formdata that I am sending. Can you please suggest header and other information, if I missed out.

  export const postImage = async state => {  

    let formData = new FormData();

    formData.append('image', {
      uri : state.photo.uri,
      type: state.photo.type,
      name : state.photo.fileName
    });


    const config = {
      headers: {
        'Content-Type': 'multipart/form-data',
        Accept: "application/x-www-form-urlencoded",
        'Accept': 'application/json'
      },
    };

    try {
    return $http.post('/image/save', formData, config)
    .then(response => response)
    .catch(error => error)
    } catch(error) {
        console.log(error)
    }
  }

Environment: - Axios Version ^0.19.2 - Additional Library Versions [React 16.11.0, React Native 0.62.1]

5

5 Answers

2
votes

There's an issue with flipper, upgrading it to 0.39.0 and above works

This issue is being tracked here: https://github.com/facebook/react-native/issues/28551

Fix: https://github.com/facebook/flipper/issues/993#issuecomment-619823916

This should be fixed in version 0.39.0. To upgrade, edit android > gradle.properties

# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.39.0  // edit this manually
2
votes

Make sure the mime type matches the file you are uploading. For me, it was the issue.

1
votes

This issue took me more than 5 hours to resolve. I was about to give up when I was finally able to resolve the issue.

The issue that I was facing which is close to what you are mentioning is that I was getting NetworkError when using expo-image-picker and trying to upload the file using axios. It was working perfectly in iOS but not working in android.

This is how I solved the issue.

There are two independent issues at action here. Let's say we get imageUri from image-picker, then we would use these following lines of code to upload from the frontend.

const formData = new FormData();
formData.append('image', {
 uri : imageUri,
 type: "image",
 name: imageUri.split("/").pop()
});

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.

The final working solution is:

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()
});
1
votes

This is an issue with flipper.Upgrade the flipper version in gradle.properties to 0.43.0+ and it will be fixed

1
votes

change this line: form_data.append('image', data);

To form_data.append('image', JSON.stringify(data));

where data is from the image picker.

from https://github.com/react-native-image-picker/react-native-image-picker/issues/798

You need to add this uesCleartextTraffic="true" to the AndroidManifest.xml file found inside the dir android/app/src/main/AndroidManifest.xml

<application ... android:usesCleartextTraffic="true"> Then, Because of issue with Flipper Network.

I commented initializeFlipper(this, getReactNativeHost().getReactInstanceManager())

in this file /android/app/src/main/java/com/{your_project}/MainApplication.java

Also, commenting out line number 43 in this file android/app/src/debug/java/com/**/ReactNativeFlipper.java

line43: builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));