Search code examples
node.jsgoogle-cloud-platformgoogle-cloud-storagegoogle-iam

Download object from GCP's Storage using NodeJS


I'm using @google-cloud/storage to access objects inside a Google Cloud Storage bucket from a node application, but I can't make it work.

I've created a Service Account on the GCP's console, and assigned the Storage Admin role to it, but when I try to get a file I get this message:

service-account-user@my-project-5411148.iam.gserviceaccount.com does not have storage.objects.get access to my-bucket-45826813215/some-object.

Looking at the bucket's permissions tab, I can see the service account is listed there with the inherited annotation and I haven't set any specific permissions to the objects.

My code looks like this:

const { Storage } = require('@google-cloud/storage');
const config = require('./config');
const storage = new Storage({ 'keyFilename': config.configFullPath('gcloud') });

const privateBucket = storage.bucket('my-bucket-45826813215'); 

let objectDownload = async (filename) => {
    let file = privateBucket.file(filename);
    let result = await file.download();
    return result;
}

objectDownload('some-object')
    .then(() => {
        console.log('Done');
    })
    .catch((err) => {
        console.log(err.message);
    });

Any ideas on what I'm doing wrong?


Solution

  • I am able to download the file with a Storage Admin Role. Below are the process which I followed

    1. Create Project enter image description here

    2. Go to IAM and select service account

    enter image description here

    3. Select create-service account enter image description here

    4. select role for service account enter image description here

    5. Create key

    enter image description here enter image description here enter image description here

    Below is working code:

    const path = require('path');
    const {Storage} = require('@google-cloud/storage');
    
    
    async function test() {
    
    const serviceKey = path.join(__dirname, './keys.json')
    
    
    const storageConf = {keyFilename:serviceKey}
    
    const storage = new Storage(storageConf)
    
    const downlaodOptions = {
          destination: __dirname+'/test.jpg'
        };
    
        try {
        let res =await storage
          .bucket('storage1232020')
          .file('test.jpg')
          .download(downlaodOptions); 
       }
       catch(err){
        console.log(err)
       }
    
    }
    
    test()
    

    Note: Make sure

    1. The service account and bucket be created under a project. For example, I created a bucket and service account for project storage-dem01232020

    2. You are passing key properly to code

    Ways to download file

    const {Storage} = require('@google-cloud/storage');
    const storage = new Storage();
    const myBucket = storage.bucket('my-bucket');
    
    const file = myBucket.file('my-file');
    
    //-
    // Download a file into memory. The contents will be available as the
    second
    // argument in the demonstration below, `contents`.
    //-
    file.download(function(err, contents) {});
    
    //-
    // Download a file to a local destination.
    //-
    file.download({
      destination: '/Users/me/Desktop/file-backup.txt'
    }, function(err) {});
    
    //-
    // If the callback is omitted, we'll return a Promise.
    //-
    file.download().then(function(data) {
      const contents = data[0];
    });
    

    Refer below link for more detials: https://googleapis.dev/nodejs/storage/latest/File.html#download