Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

208
Views
Downloading multiple files from Google Cloud Storage in NodeJS

I am hosting a NodeJS app on Heroku in which users can upload their own images. I am hosting those images on Google Cloud Storage because Heroku will wipe them if they weren't part of the deployment. So I check to see if the images are on the server. If they aren't on the server, then they are requested from GCS.

When I try to download multiple images from a GCS Bucket to my host server, all image files downloaded will be the same as the last image in the request. If I have 1 image in the request, then the downloaded image will be correct. If I have more than one file, then only the last downloaded image is correct. The rest of the files have the correct filename, but the image downloaded for all of them are identical.

const fs = require('fs');
const path = require('path');
const { Storage } = require('@google-cloud/storage');
const mongoose = require('mongoose');
const User = mongoose.model('Users');
const filePath = 'uploads';

//GET REQUEST WILL START HERE
const recipesReadList = (req, res) => {
  getUser(req, res, (req, res) => {
    User.findById(req.params.userid)
      .select('recipe')
      .exec((err, user) => {
        if (user.recipe && user.recipe.length > 0) {
          user.recipe.forEach((recipe) => {
            if (!fs.existsSync(`uploads/${recipe.imageName}`)) {
              downloadImage(recipe.imageName);
            }
          });
          return res.status(200).json(user.recipe);
        }
      });
  });
};

const getUser = (req, res, callback) => {
  if (req.payload && req.payload.email) {
    User.findOne({ email: req.payload.email }).exec((err, user) => {
      callback(req, res, user.userName);
    });
  }
};

const downloadImage = async (file) => {
  downloadFromGCS(file).catch(console.error);
};

const GCS_Storage = new Storage({
  projectId: process.env.GCLOUD_PROJECT,
  keyFilename: path.join(__dirname, '../../', `${process.env.GCS_KEYFILE}`),
});

let downloadFileName = '';

async function downloadFromGCS(fileName) {
  downloadFileName = fileName;
  let foundFile = false;

  const options = {
    destination: filePath + '/' + fileName,
  };

  const [files] = await GCS_Storage.bucket(process.env.GCS_BUCKET).getFiles();

  files.forEach((file) => {
    if (file.name === fileName) {
      foundFile = true;

      // Download the file to host storage
      GCS_Storage.bucket(process.env.GCS_BUCKET)
        .file(downloadFileName)
        .download(options);
    }
  });

  if (foundFile === false) {
    console.log(`File not found on cloud storage: ${fileName}`);
  }
}

module.exports = {
  recipesReadList,
};

I have tried using async/await (awaiting the download) based on this post, but that yielded the same results. I'm not sure how to validate if a file on the server has completed a download.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I was creating a reprex code sample, per request from @DougStevenson (thanks for that, I was looking in the wrong place), and I solved the issue. At some point in development, I had created a variable outside the scope of a function because it wasn't behaving as expected. I don't remember exactly what it was doing at the time. Regardless, changing the scope of the variable fixed the issue.

I changed this:

let downloadFileName = '';

async function downloadFromGCS(fileName) {
  downloadFileName = fileName;

to this

//let downloadFileName = '';
    
async function downloadFromGCS(fileName) {
  let downloadFileName = fileName;

And now the issue is resolved.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!