Search code examples
node.jsfile-uploadgoogle-cloud-storageejsfilepath

Error when uploading file to Google Cloud Storage in node.js


I have this form element:

  <form action="/upload" method="POST">
      <input type="file" id="img" name="image" accept="image/*" class="btn"/>
      <button type="submit" class="btn">Upload</button>
  </form>

When I submit the form, the post request is getting the file name of the image through body-parser.

app.post("/upload", (req, res) => {
  console.log(req.body.image);
  const filename = req.body.image;
  async function uploadFile() {
    await storage.bucket(bucketName).upload(filename)
  }
  uploadFile().catch(console.error);
  res.redirect("/upload");
});

The console.log returns just the file name image.jpg without the path. When the uploadFile() method is called it returns an error saying that the file path does not exist, because it is saying the file path is: C:\\Users\Owner\Desktop\Serverfolder\image.jpg which is completely wrong.

So how do I prepend the right file path that google cloud will accept? I know that the browser will protect the actual file path for file uploads, but it is not filling in the temporary or fakepath so that the image can be uploaded.

Please help, because the google cloud documentation is annoyingly vague on the matter...


Solution

  • The file path should be referenced within the scope of your server. What you can do is store the file in a folder called uploads with multer. Then reference the relative path into uploadFile() and upload it. It should get the file then. Once you've uploaded you can then use the fs node package to delete the file.

    Here is the multer configuration i used

    // Multer config
    const multer = require('multer');
    var storage = multer.diskStorage({
        destination: function (req, file, cb) {
          cb(null, 'blog-images/')
        },
        filename: function (req, file, cb) {
            let tempImageName = file.mimetype.toString().split('/')[1];
            req.imageName = tempImageName
          cb(null, tempImageName)
        }
      })
      var upload = multer({ storage: storage })
    

    And this is the code that uploads it

    app.post('/upload', upload.single('image'), (req, res)=>{
     //blog-images below is the custom folder i created. I can easily reference it
    //since it is a part of the server
      let imagePath = `blog-images/${req.imageName}`
      // The code is split here but essentially, it solves the file path problem
      uploadBlog(imagePath, req.body)
      .then( uploadRef => {
        // The fs module deletes it from the folder so you don't have to worry about
        // uncessary files
        fs.unlink(imagePath, ()=>{
          res.send('upload success')
         })
       }).catch(err => console.log(err.message))
    })