【问题标题】:Upload multiple images on Firebase using NodeJS and Busboy使用 NodeJS 和 Busboy 在 Firebase 上上传多张图片
【发布时间】:2020-02-16 01:18:15
【问题描述】:

我创建了使用 NodeJS 和 Busboy 在 Firebase 上上传单个图像的函数,该函数返回图像 url。允许的图片扩展名只有 .jpg.png。它将生成随机文件名并使用storageBucket 创建文件路径。

但是,我正在努力重构此功能,因此我可以上传多张图片。我尝试了几次尝试,但没有运气。如果所有图像都成功上传,它应该返回图像 url 数组。

这是我的单张图片上传功能:

const { admin, db } = require("./admin");
const config = require("./config");

exports.uploadImage = (req, res, url, folder) => {
    const BusBoy = require("busboy");
    const path = require("path");
    const os = require("os");
    const fs = require("fs");

    const busboy = new BusBoy({ headers: req.headers });

    let imageFileName;
    let imageToBeUploaded = {};

    busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
        if (mimetype !== "image/jpeg" && mimetype !== "image/png") {
            return res
                .status(400)
                .json({ error: "Wrong file type submitted!" });
        }
        // Getting extension of any image
        const imageExtension = filename.split(".")[
            filename.split(".").length - 1
        ];
        // Setting filename
        imageFileName = `${Math.round(
            Math.random() * 1000000000
        )}.${imageExtension}`;
        // Creating path
        const filepath = path.join(os.tmpdir(), imageFileName);
        imageToBeUploaded = { filepath, mimetype };
        file.pipe(fs.createWriteStream(filepath));
    });
    busboy.on("finish", () => {
        admin
            .storage()
            .bucket()
            .upload(imageToBeUploaded.filepath, {
                destination: `${folder}/${imageFileName}`,
                resumable: false,
                metadata: {
                    metadata: {
                        contentType: imageToBeUploaded.mimetype
                    }
                }
            })
            .then(() => {
                const imageUrl = `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o${folder}%2F${imageFileName}?alt=media`;
                if (url === `/users/${req.user.alias}`) {
                    return db.doc(`${url}`).update({ imageUrl });
                } else {
                    return res.json({ imageUrl });
                }
            })
            .then(() => {
                return res.json({
                    message: "Image uploaded successfully!"
                });
            })
            .catch(err => {
                console.log(err);
                return res.status(500).json({ error: err.code });
            });
    });
    busboy.end(req.rawBody);
};

有什么建议可以继续吗?

【问题讨论】:

    标签: node.js firebase image-uploading busboy


    【解决方案1】:

    您的代码几乎完成了,您所要做的就是创建一个 Promise 数组并等待全部解决。

    let imageFileName = {}
    let imagesToUpload = []
    let imageToAdd = {}
    //This triggers for each file type that comes in the form data
    busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
        if (mimetype !== "image/jpeg" && mimetype !== "image/png") {
            return res
                .status(400)
                .json({ error: "Wrong file type submitted!" });
        }
        // Getting extension of any image
        const imageExtension = filename.split(".")[
            filename.split(".").length - 1
        ];
        // Setting filename
        imageFileName = `${Math.round(
            Math.random() * 1000000000
        )}.${imageExtension}`;
        // Creating path
        const filepath = path.join(os.tmpdir(), imageFileName);
        imageToAdd = { 
           imageFileName
           filepath, 
           mimetype };
        file.pipe(fs.createWriteStream(filepath));
        //Add the image to the array
        imagesToUpload.push(imageToAdd);
       });
    
    busboy.on("finish", () => {
            let promises = []
            let imageUrls = []
            imagesToUpload.forEach(imageToBeUploaded => { 
    imageUrls.push(`https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o${folder}%2F${imageFileName}?alt=media`)
                        promises.push(admin
                            .storage()
                            .bucket()
                            .upload(imageToBeUploaded.filepath, {
                                 destination: `${folder}/${imageFileName}`,
                                 resumable: false,
                                 metadata: {
                                     metadata: {
                                         contentType: imageToBeUploaded.mimetype
                                     }
                                 }
                             }))
                    })
              try{      
                  await Promises.all(resolve)
                  res.status(200).json({msg: 'Successfully uploaded all images', imageUrls})
    }catch(err){ res.status(500).json(err) }
                });
            busboy.end(req.rawBody);
    

    你应该可以上传它们,只需将所有承诺放在一个数组中并使用Promise.all 方法等待它们解决。我用 async/await 做到了,因为我一直这样做,但我想你用回调做这件事没有问题。

    另外代码比较乱,主要是我不知道怎么用这个文本编辑器,希望你还能看懂?

    【讨论】:

    • 谢谢!它正在工作!请在您的函数中添加“异步”,以便我接受这个答案,否则会引发错误。
    • 我已经对我的函数使用了异步,但它仍然给我一个错误 - pastebin.com/YKgCitMu
    【解决方案2】:

    Samuel Vera 的回答几乎是正确的。推送到 imageUrls 数组时出现一些拼写错误和逻辑错误。

    这里,完整的代码修复:

    const BusBoy = require('busboy');
    const path = require('path');
    const os = require('os');
    const fs = require('fs');
    
    let fields = {};
    
    const busboy = new BusBoy({ headers: request.headers });
    
    let imageFileName = {};
    let imagesToUpload = [];
    let imageToAdd = {};
    let imageUrls = [];
    
    busboy.on('field', (fieldname, fieldvalue) => {
        fields[fieldname] = fieldvalue;
    });
    
    busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
        if (mimetype !== 'image/jpeg' && mimetype !== 'image/png') {
            return res
                .status(400)
                .json({ error: 'Wrong file type submitted!' });
        }
    
        // Getting extension of any image
        const imageExtension = filename.split('.')[
            filename.split('.').length - 1
        ];
    
        // Setting filename
        imageFileName = `${Math.round(Math.random() * 1000000000)}.${imageExtension}`;
    
        // Creating path
        const filepath = path.join(os.tmpdir(), imageFileName);
        imageToAdd = {
            imageFileName,
            filepath,
            mimetype,
        };
    
        file.pipe(fs.createWriteStream(filepath));
        //Add the image to the array
        imagesToUpload.push(imageToAdd);
    });
    
    busboy.on('finish', async () => {
        let promises = [];
    
        imagesToUpload.forEach((imageToBeUploaded) => {
            imageUrls.push(
                `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o/${imageToBeUploaded.imageFileName}?alt=media`
            );
            promises.push(
                admin
                    .storage()
                    .bucket()
                    .upload(imageToBeUploaded.filepath, {
                        resumable: false,
                        metadata: {
                            metadata: {
                                contentType: imageToBeUploaded.mimetype,
                            },
                        },
                    })
            );
        });
    
        try {
            await Promise.all(promises);
            
            return response.json({
                message: `Images URL: ${imageUrls}`,
            });
            
        } catch (err) {
            console.log(err);
            response.status(500).json(err);
        }
    });
    
    busboy.end(request.rawBody);
    

    无论如何,谢谢塞缪尔:)

    【讨论】:

      猜你喜欢
      • 2017-07-23
      • 2017-11-04
      • 2020-08-14
      • 2017-06-29
      • 2018-09-30
      • 2018-05-21
      • 2016-10-12
      • 2020-12-05
      • 2016-05-08
      相关资源
      最近更新 更多