'React-Native multipart photo upload not working in android

I'm trying to send/upload image file to my back-end serve using fetch multipart upload in react-native, but fetch multipart form data upload is not working for android, however I tried different examples.

Image upload multipart form data API is based on php and its working for iOS react-native app.

I am using react-native-photo-upload library for taking image.

storePicture(PicturePath:string) {
console.warn(PicturePath);
if (PicturePath) {
  const apiUrl = `${Constants.APIHOST}updateprofileimage.php`;
  // Create the form data object
  var data = new FormData();
  data.append('profileimage', { uri:PicturePath, name: 'profileimage.jpg', type: 'image/jpg/jpeg' });
  data.append('accesstoken', this.state.user.sAccessToken);
  data.append('react-native', 1);

  // Create the config object for the POST // You typically have an OAuth2 token that you use for authentication
  const config = { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'multipart/form-data;' }, body: data };
  fetch(apiUrl, config)
  .then(responseData => { // Log the response form the server
    // Here we get what we sent to Postman back
    console.warn(`response:${responseData}`);
  })
  .catch(err => {
    console.warn(err);
  });
}}

Here is the example how I am calling storePicture() function.

<PhotoUpload onResizedImageUri={
        avatar => {
          if (avatar) {
            this.storePicture(avatar.path);
          }
        }}
      >
        <Image source={{uri: this.state.user.sProfileImageUrl}} style={{resizeMode:"cover", marginTop:8.0, backgroundColor:'transparent', height:120.0, width:120, borderRadius:60.0, borderWidth:0.0, borderColor:'transparent'}}/>
      </PhotoUpload>


Solution 1:[1]

uploadProfileImage = async (image:var) => {
this.setState({
  loading: true
});
var RNFS = require('react-native-fs');
const path = Style.IS_IOS ? image.uri : image.path;
var fileName = path.split('/').pop();
var fileType = fileName.split('.').pop();
var filePath = Style.IS_IOS ? path : 'file://' + path;

const apiURL = `${Constants.APIHOST}updateprofileimage.php`;
const formData = new FormData();
formData.append('accesstoken', this.state.user.sAccessToken);
formData.append('reactnative', 1);
formData.append('profileimage', {
  uri:filePath,
  name: fileName,
  type: `image/${fileType}`,
});
try {
  const response = await fetch(apiURL, {
    body: formData,
    method: 'POST',
    headers: {
      'Content-Type': 'multipart/form-data',
      'Accept': 'application/json',
    },
  })
  const json = await response.json()
  this.handleUploadImageResponse(json);
} catch (err) {
  this.setState({
    loading: false
  },console.log('catch Error: '+ err));
}

}

I am answering my own question as I haven't found any valid answer for the sake of other users, who are facing same issue.

Please let me know if I can improve my answer/post or in case any help is needed from me.

Solution 2:[2]

Image Upload to an API by Multipart FormData

uploadPicture = () => {
  console.log(
    "Image Upload urI = " + JSON.stringify(this.state.imageSourceUri.uri)
  );
  this.setState({ loading: true });

  const form = new FormData();
  form.append("fileToUpload", {
    uri: this.state.imageSourceUri.uri,
    type: "image/jpg",
    name: "12334"
  });
  fetch("http://119.82.97.221/HPBSProjectApi2/api/HPBS/PostFormData", {
    method: "post",
    body: form
  })
    .then(response => response.json())
    .then(response => {
      console.log("response = " + response);
      this.setState({
        loading: false
      });
    });
};

Solution 3:[3]

the problem is the type field in the FormData, use mime to resolve it. Images must be image/jpeg.

 const formData = new FormData();
 formData.append("image",{..., name, uri, type: mime.getType(uri)}));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rajender Kumar
Solution 2 Ru Chern Chong
Solution 3 J. Jerez