Network Request Failed while uploading image to server

I’ve been trying to solve this issue for days but I couldn’t find any solution, I don’t know if this is a problem with the expo version, I’m using the 35.0.0, in the app, I want the user to insert a description in a TextInput an also take a picture with the camera, I’m using expo-image-picker, everything works perfectly if I only send text to my database but when I implemented formData to send the file I get this error on my android device and emulator, I’m using localhost, so my devices are in the same network.

Here is my code:

  constructor(props){
     super(props) 
      this.state = {
          InputDescripcion:'',
          image:null
      }
  }

This is the method I’m using to post the content

  InsertUser = ()=>{
      //constant varaibles that equal propertes in state
      const {InputDescripcion} = this.state;
      const {image} = this.state;

      const formData = new FormData();
      formData.append('Descripcion', InputDescripcion);

      formData.append('photo', {
        uri: Platform.OS === "android" ? image.uri : image.uri.replace("file://", ""),
        type: 'image/jpeg',
        name: 'photo.jpeg'});
      //API that use fetch to input data to database via backend php script
      fetch('http://192.168.1.59/911Occidente/TestAlert.php',{
          method: 'POST',
          Accept: 'application/json',
          'Content-Type': 'multipart/form-data',
             body: formData
          })
        .then((response) => response.text())
        .then((responseJson) =>{
            //alert(responseJson);
            if(responseJson == "ok"){
           
                alert("Success");
           
            }else{
            
               alert(responseJson);
            }
        })
        .catch((error)=>{
            console.error(error);
        });
        
  Keyboard.dismiss(); 
      }

Here is the render method:

render(){
let { image } = this.state;
return(

                          <Button
                          
                          title="Add Image"
                          onPress={this.takePicture}
                          />
              
                          <Button
                          style = {{marginTop:20}}
                          title="Reset"
                          onPress={this.resetImage}
                          />
                      
                  </View>  

            <View style={{alignSelf:"center"}}>
                {image &&
                <Image source={{uri:image }} style={{ width: 300, height: 300 }} />}
            </View>

            <View style={{marginTop:100, alignSelf:'center'}}>                             
                <TouchableOpacity style={styles.button}  onPress={this.InsertUser}>
                    <Text style={styles.buttonText} > Send</Text>
                 </TouchableOpacity>  
            </View>
     ):

}

I’ve been looking for many solutions but any of them worked for me, I get this error when I want to use formData, could this be related to my expo version?

Please , i am having this issue, did you manage to fix it?

I am also having same issue…
Any solution??

Hey, I am also facing the same issue, did anyone solved the problem?

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

I hope this helps to solve your problem. :slight_smile:

21 Likes

Great help! Thanx!

1 Like

I love you

1 Like

Dude, I can’t thank you enough for discovering the solution. Your 5 hours spent won’t get in vain.

1 Like

Many Thanks for your Information, it’s really helpful

Hi l can’t get mine to work confirm that you are using axios for this cause l am using the built in Js Fetch could that be a problem

I am using axios for mine. But i think it is unrelated to either axios or fetch.

Okay can l show you my code
const uploadImage = () => {

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

    const formData = new FormData();

    formData.append('image', {

     uri : newImageUri,

     type: mime.getType(newImageUri),

     name: newImageUri.split("/").pop()

    });

   fetch(`http://172.20.10.6:5000/image/${userId}`, {

        method:'POST',

        Accept: 'application/json',

        'Content-Type': 'multipart/form-data',

        body: formData

    })

    .then((res) => {

            console.log(res)

    }).catch((err) => {

        console.log(err)

    })

}

Could you please take a look my code

I don’t know the issue exactly. First, try to see if the request is reaching the server or not by not appending the image to the request. If it does not, then you need to probably first debug that. Once it is reaching the server, check what the newImageUri by console logging it before const formData = new FormData();. Make sure that if the path to file is /user/.../path/to/file.jpg, then the newImageUri should be equal to file:///user/.../path/to/file.jpg. Other than that, I may not be able to help you much.

Alright thank you

i just logged in here to say thank you :""")))
as we say in urdu: “tum bohot mast kaam karte ho maqsood bhai”
search this phrase up on YouTube you’ll know more XD

Thanks a lot man.

I was tend to eject expo because of this problem what I can not found the cause until I read this.

Thank you so MUCH!!!

but I think this should be the caveat of the expo api. expo should improve the api, keep the behavior the same.

Hey everyone! we’ll look into this, but I just wanted to mention that implementing that workaround unguarded can be pretty dangerous:

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

if we fix this in a future release, the above code would result in
file://///my_file_path.jpg so you may want to add a check for isValidUrl or something like that before working around this (that’s also helpful since this issue seems to be Android-only anyways)

2 Likes

Thank you man
saved my day