0

My React-Native iOS front-end can not upload images to my Node.JS (Express + Multer) back-end.

My front-end is React Native Android & iOS. The Android version works fine with no issues, however, uploading images from and iOS device doesn't work most of the time.

Once the upload request is sent, I can see the image file is added in FTP, however, very slowly, like a few KB every second. An image of 500 KB may take 3 minutes or more till the request times out. The file is added to the server partially and I can see change in size with each refresh.

Some [iOS] devices had no issues at all, uploads fast, however, the vast majority of devices are running into this issue.

No connectivity issues. The same host and network work perfectly with Android. Same with some iOS devices.

This is not limited to a specific iOS version or device. However, the devices who had the issue always have it, and those that don't, never have it.

How can I troubleshoot this?

POST request:

router.post('/image', (req, res) => {
    console.log('image')
    upload(req, res, (error) => {
        if (error) {

            console.log(error)
            return res.send(JSON.stringify({
                data: [],
                state: 400,
                message: 'Invalid file type. Only JPG, PNG or GIF file are allowed.'
            }));
        } else {
            if (req.file == undefined) {
                console.log('un')

                return res.send(JSON.stringify({
                    data: [],
                    state: 400,
                    message: 'File size too large'
                }));
            } else {
                var CaseID = req.body._case; // || new mongoose.Types.ObjectId(); //for testing
                console.log(req.body._case + 'case')
                var fullPath = "uploads/images/" + req.file.filename;
                console.log(fullPath);
                var document = {
                    _case: CaseID,
                    path: fullPath
                }

                var image = new Image(document);

                image.save(function(error) {
                    if (error) {
                        console.log(error)
                        return res.send(JSON.stringify({
                            data: [],
                            state: 400,
                            message: 'bad request error'
                        }));
                    }
                    return res.send(JSON.stringify({
                        data: image,
                        state: 200,
                        message: 'success'
                    }));
                });
            }
        }
    });

});

Upload.js:

const multer = require('multer');
const path = require('path');

//image upload module

const storageEngine = multer.diskStorage({
    destination: appRoot + '/uploads/images/',
    filename: function (req, file, fn) {
        fn(null, new Date().getTime().toString() + '-' + file.fieldname + path.extname(file.originalname));
    }
});


const upload = multer({
    storage: storageEngine,
    // limits: {
    //     fileSize: 1024 * 1024 * 15 // 15 MB
    // },
    fileFilter: function (req, file, callback) {
        validateFile(file, callback);
    }
}).single('image');

var validateFile = function (file, cb) {
    // allowedFileTypes = /jpeg|jpg|png|gif/;
    // const extension = allowedFileTypes.test(path.extname(file.originalname).toLowerCase());
    // const mimeType = allowedFileTypes.test(file.mimetype);
    // if (extension && mimeType) {
    //     return cb(null, true);
    // } else {
    //     cb("Invalid file type. Only JPEG, PNG and GIF file are allowed.")
    // }
    var type = file.mimetype;
    var typeArray = type.split("/");
    if (typeArray[0] == "image") {
      cb(null, true);
    }else {
      cb(null, false);
    }
};


module.exports = upload;

React Native Upload function:

    pickImageHandler = () => {
            ImagePicker.showImagePicker(this.options1, res => {
                    if (res.didCancel) {
                    } else if (res.error) {
                    } else {
                            this.setState({upLoadImage:true})
                            var data = new FormData();
                            data.append('image', {
                              uri: res.uri, 
                              name: 'my_photo.jpg',
                              type: 'image/jpg'
                            })
                            data.append('_case',this.state.caseID)

                            fetch(url+'/image'
                            , {method:'POST',
                            body:data
                            }
                             )
                            .then((response) => response.json())
                            .then((responseJson) =>
                            {
                                    this.setState(prevState => {
                                            return {
                                                    images: prevState.images.concat({
                                                            key: responseJson._id,
                                                            src: res.uri
                                                    })
                                            }

                                    }

                                    )   
                                    this.setState({upLoadImage:false})


                            })

                            .catch((error) =>
                            {
                              alert(error);
                            });


                    }
            }
            )
    }

Any suggestions?

Thanks

Abdulrahman Hassoun
  • 1,151
  • 1
  • 9
  • 15
  • Can you set up an example for us? – Train Aug 05 '19 at 19:04
  • @Train could you suggest some way? – Abdulrahman Hassoun Aug 05 '19 at 20:41
  • You can use js fiddle, also take a look at this lengthy answer https://stackoverflow.com/questions/5823722/how-to-serve-an-image-using-nodejs – Train Aug 05 '19 at 21:21
  • The problem is solved. And it has never occurred in the past 60 days. NOTHING has changed, front-end, back-end, and the host OS, nothing at all has changed, yet it worked, out of blue. And by the way, when the problem was present, it was only in my country (all ISP), same phone in another countries worked fine. – Abdulrahman Hassoun Oct 12 '19 at 10:38

1 Answers1

1

I saw your answer from UpWork please try this way, I'm using API Sauce for API calls

export const addPartRedux = (data) => {
    return (dispatch, getState) => {
        console.log('addPArtREdux', data);
        const values = {
            json_email: data.token.username,
            json_password: data.token.password,
            name: data.text ? data.text : '',
            car: data.selected.ID,
            model: data.selectedSub.ID,
            make_year: data.selectedYear,
            type: data.type,
            ImportCountry: data.import_image ? data.import_image : '',
            FormNumber: data.number ? data.number : '',
            do: 'insert'
        };
        const val = new FormData();
        Object.keys(values).map((key) =>
            val.append(key, values[key])
        );
        if (data.imageok) {
            val.append('image', {
                uri: data.image.uri,
                type: data.image.type,
                name: data.image.name
            });
        }
        dispatch(loading());
        api
            .setHeader('Content-Type', 'multipart/form-data;charset=UTF-8');
        api
            .post('/partRequest-edit-1.html?json=true&ajax_page=true&app=IOS',
                val,
                {
                    onUploadProgress: (e) => {
                        console.log(e);
                        const prog = e.loaded / e.total;
                        console.log(prog);
                        dispatch(progress(prog));
                    }
                })
            .then((r) => {
                console.log('Response form addPartRedux', r.data);
                if (r.ok === true) {
                    const setting = qs.parse(r.data);
                    dispatch(addpart(setting));
                } else {
                    dispatch(resetLoading());
                    dispatch(partstError('Error Loading '));
                }
            })
            .catch(
                (e) => {
                    console.log('submitting form Error ', e);
                    dispatch(resetLoading());
                    dispatch(partstError('Try Agin'));
                }
            );
    };
};

MShokry
  • 81
  • 8