1

I am trying to upload a file to google storage bucket. The file will be sent to the nodejs backend route using post method and form-data. I have read google storage documents regarding uploading the files.

I am not getting the idea about how should i receive the file and assign it to filename variable so that it can be uploaded to google storage bucket. Something just like this.

const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

test: async (req, res, next) => {
    const filename = req.body.file

    // const bucketName = 'Name of a bucket, e.g. my-bucket';
    // const filename = 'Local file to upload, e.g./local/path/to/file.txt';
    await storage.bucket(bucketName).upload(filename, {

        gzip: true,
    
        metadata: {
            cacheControl: 'public, max-age=31536000',
        },
    });

    console.log(`${filename} uploaded to ${bucketName}.`);
    }
}
  • You need to call this function once the file upload. For that you can use file upload package. One good one is this: https://github.com/react-dropzone/react-dropzone – Shubham Verma Sep 05 '20 at 16:47
  • Actually, i am working at the node.js part, where i will receive the file using post method and from the request part , i will upload it to google storage bucket. – anita shrivastava Sep 05 '20 at 16:49
  • See this tutorial [then](https://www.youtube.com/watch?v=pGSzMfKBV9Q). You will get the context – Shubham Verma Sep 05 '20 at 16:53
  • I have seen that too. In fact, i have tried looking everywhere on the internet. Actually, sending a file is just a part of a whole form. I will receive json +file. I will save the file in cloud storage and the url of that storage will be saved in my mongodb collection along with the other form details. – anita shrivastava Sep 05 '20 at 17:00

2 Answers2

2

I have created the code below from the samples of node-formidable library to handle form data and the snippets for nodejs-Storage library. Indeed I tested it and works pretty well, tough you may want to customize filenames and the like.

const express = require('express');
const formidable = require('formidable');
const {Storage} = require('@google-cloud/storage');
const bucket = 'yourBucketName';

async function uploadFile(bucket, filename) {
  const storage = new Storage();
  const params = {metadata: {cacheControl: 'public, max-age=31536000'}};
  await storage.bucket(bucket).upload(filename, params);
  console.log(`${filename} uploaded to ${bucket}.`);
}

const app = express();

app.get('/', (req, res) => {
  res.send(`
    <h2>With <code>"express"</code> npm package</h2>
    <form action="/api/upload" enctype="multipart/form-data" method="post">
      <div>Text field title: <input type="text" name="title" /></div>
      <div>File: <input type="file" name="someExpressFiles" multiple="multiple" /></div>
      <input type="submit" value="Upload" />
    </form>
  `);
});

app.post('/api/upload', (req, res, next) => {
  const form = formidable();

  form.parse(req, (err, fields, files) => {
    if (err) {
      next(err);
      return;
    }
    let imgPath = files.someExpressFiles.path;
    uploadFile(bucket, imgPath).catch(console.error);
    res.json({ fields, files });
  });
});

app.listen(8080, () => {
  console.log('Server listening on http://localhost:8080 ...');
});
Happy-Monad
  • 1,962
  • 1
  • 6
  • 13
0

The gg docs solution only works in development. If you are in production, your Nodejs won't aware of file path

So follow these steps may help you:

Step 1: Encode your image to base64 and send it to backend.

Step 2: From your backend, you have to decode this base64 and upload it to gg cloud storage

this link is helpful: How do I upload a base64 encoded image (string) directly to a Google Cloud Storage bucket using Node.js?

BadJuju
  • 195
  • 2
  • 11