Search code examples
node.jsreactjsimagereact-nativemulter

How to upload images to MongoDB in MERN stack using react native?


I'm making an app, and in my app I'm trying to allow the users to upload images to the database. For this app I'm using the MERN (with react native, instead of react). I have a route to upload images to the database, and a redux action where the route is called. Below I've included my code for the two. I'm wondering how I call the route within the action and then pass the image data into the route? Any help or direction would be much appreciated. Thank you!

Redux Action:

// Add Images to profile
export const addImages = (userImages) => async dispatch => {
  let formData = new FormData();
  formData.append("userImages", userImages);
  //console.log(userImages);

  //const body = userImages;
  try {
    const res = await axios.post('http://localhost:5000/api/users/images', formData);


    dispatch({
      type: ADD_IMAGES,
      payload: res.data
    });

    //dispatch(loadUser());
    //dispatch(NavigationActions.navigate({ routeName: 'CreateProfile' }));
  } catch (err) {
    //console.log('this is the error you are looking for', err);
    const errors = err.response.data.errors;

    if (errors) {
      errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
    }

    dispatch({
      type: PROFILE_ERROR,
      payload: res.data
    });
  }
}

add images route:

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads/');
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + file.originalname);
  }
});

//const upload = multer({ storage: storage, });

const fileFilter = (req, file, cb) => {
  // reject a file
  if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
    cb(null, true);
  } else {
    cb(null, false);
  }
};

const upload = multer({
  storage: storage, limits: {
    fileSize: 1024 * 1024 * 5
  },
  fileFilter: fileFilter
});

//@route  POST api/users/images
//@desc   Store user images
//@access Private
router.post("/images", auth, upload.array('userImages', 5),
  async (req, res) => {
    //console.log(req.files);
    const files = req.files;
    //console.log(files);
    if (!files) {
      return res.status(400).json({ errors: [{ msg: 'Please add photos' }] });
    }

    console.log("here");
    try {
      console.log("files: " + files);
      let desiredUser = await User.findById(req.user.id);


      if (desiredUser) {
        //desiredUser.bio = bio;
        for (let i = 0; i < 5; i++) {
          console.log("files[i]: " + files[i])
          //console.log(files[i].filename.toString());
          desiredUser.userImages.push(files[i].filename.toString());
        }
        //desiredUser.userImage = files
        await desiredUser.save();
        return res.json(desiredUser);
      } else {
        return res.status(400).json({ errors: [{ msg: 'Please add photo' }] });
      }
    } catch (err) {
      console.error(err.message);
      return res.status(500).send('Server error');
    }
  });

Solution

  • Upload the images first to storage service like AWS S3 or Firebase storage using their API. Once the API returns you the URL of uploaded image you can update that URL in your mongodb document.