I am no JavaScript expert, and I have managed to hack together a node.js script that does exactly what I want it to do: upload images contained within a folder to Google Cloud Storage for a Firebase project, and then return the public access URLs. Given that I have limited experience with node.js combined with GC Storage, please advise me on any issues that running this code over approximately 200 images in the folder may cause.

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

const projectId = 'XXXXXXX';

//Creates a client
const storage = new Storage({
    projectId: projectId,
    keyFilename: 'auth.json'

// Reference the bucket
var bucket = storage.bucket('XXXXXXX.appspot.com');

//This reads the folder where the images are stored
fs.readdir('ImagesToUpload', (err, files) => {

    if( err ) {
        console.error( "Could not read the directory.", err );
        process.exit( 1 );

    files.forEach(function( file, index ) {

        var filePath = 'ImagesToUpload/'


        // Upload a local file to a new file to be created in the bucket
        bucket.upload(filePath += file, (err, file) => {
            if (err) { return console.error(err); }
            let publicUrl = `https://firebasestorage.googleapis.com/v0/b/${projectId}.appspot.com/o/${file.metadata.name}?alt=media`;

1 Answer 1


Looks good. A few nits:

  1. You might as well use const where you can, and let when that doesn't work. You can avoid var completely.

  2. Instead of var filePath = 'ImagesToUpload/'-- and then modifying filePath with +=, just set filePath to the correct path immediately, ie. const filePath = 'ImagesToUpload' + file. This is just simpler and easier to read.

  3. A subtler point: The logs are providing you your only reference to the file mapping onto the server. I'm concerned that these async functions won't necessarily run in order. Consider a huge file followed by a small file. Would the loop of files allow bucket.upload calls to be running at the same time? I would assume so. The small one would complete before the large one. If this happens, it's possible that your log console.log(file) will happen out of sequence with the console.log(publicUrl). This can be solved by moving the first console log into the loop right before the publicUrl log.

  4. Unused arguments at the end of the list can be omitted safely in JS, so function( file, index ) can be simply function( file), or even file => if you use the new ES syntax (which you are)

  • \$\begingroup\$ Brilliant, thanks for the clear and concise answer! \$\endgroup\$
    – pho_pho
    Oct 16, 2018 at 9:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.