ShevO27
ShevO27

Reputation: 906

Fetching image fails on expo on react native on android

I use fetch sending image to a server. On iOS everythin works as expected, but on android i get Request fialed.
The uri i get from expo image picker, on IOS everything works as expected.

const form = new FormData();
      form.append('file', {
        uri: imageUri,
        name: 'file.jpg',
        fileName: 'file',
      });

fetch(api,{
      method: 'post',
      body: form,
    })
      .then(response => response.text())
      .then(textResponse => {
      console.log(textResponse);
      Alert.alert(textResponse);
      if (textResponse){
        setAccuracyResponse(textResponse);
      }
      })
      .catch(error => {
        console.error(error)
      });

on android i get this response

Network request failed
- node_modules/whatwg-fetch/dist/fetch.umd.js:535:17 in setTimeout$argument_0
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:130:14 in _callTimer
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:383:16 in callTimers
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:416:4 in __callFunction
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:109:6 in __guard$argument_0
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:364:10 in __guard
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:108:4 in callFunctionReturnFlushedQueue
* [native code]:null in callFunctionReturnFlushedQueue

Expo sdk v39
Expo version 3.28.5
node v14.15.0
npm 6.14.8

Upvotes: 2

Views: 2215

Answers (1)

ShevO27
ShevO27

Reputation: 906

There were couple issues with this. First was that 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.

So the correct approach is to use file:// instead of file: in the formData in android.

The second issue is providing proper mime type in the form data, Ex: mime-type for .jpg file would be image/jpeg and for .png file would be image/png, so you can use a "mime" npm package for this. So my final solution looks like this:

const imageUri = result.uri;
const newImageUri = Platform.OS === "android" ? "file:///" + imageUri.split("file:/").join("") : imageUri;
const form = new FormData();
  form.append('file', { //this prop can vary depends of your sever settings
    uri: newImageUri,
    type: mime.getType(newImageUri),
    name: newImageUri.split("/").pop(),
  });

The complete stack of this problem with a solution can be found here

Upvotes: 2

Related Questions