Estoy alojando una aplicación NodeJS en Heroku en la que los usuarios pueden cargar sus propias imágenes. Alojo esas imágenes en Google Cloud Storage porque Heroku las borrará si no formaron parte de la implementación. Así que verifico si las imágenes están en el servidor. Si no están en el servidor, se solicitan a GCS.
Cuando intento descargar varias imágenes de un depósito de GCS a mi servidor host, todos los archivos de imagen descargados serán los mismos que la última imagen de la solicitud. Si tengo 1 imagen en la solicitud, la imagen descargada será correcta. Si tengo más de un archivo, solo la última imagen descargada es correcta. El resto de los archivos tienen el nombre de archivo correcto, pero la imagen descargada para todos ellos es idéntica.
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, };Intenté usar async/await (en espera de la descarga) según esta publicación , pero arrojó los mismos resultados. No estoy seguro de cómo validar si un archivo en el servidor ha completado una descarga.
Estaba creando una muestra de código reprex, por solicitud de @DougStevenson (gracias por eso, estaba buscando en el lugar equivocado) y resolví el problema. En algún momento del desarrollo, había creado una variable fuera del alcance de una función porque no se comportaba como se esperaba. No recuerdo exactamente qué estaba haciendo en ese momento. De todos modos, cambiar el alcance de la variable solucionó el problema.
Cambié esto:
let downloadFileName = ''; async function downloadFromGCS(fileName) { downloadFileName = fileName;a esto
//let downloadFileName = ''; async function downloadFromGCS(fileName) { let downloadFileName = fileName;Y ahora el problema está resuelto.