[使用NodeJS和Busboy在Firebase上上传多个图像

问题描述 投票:0回答:1

我创建了使用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个回答
0
投票

您的代码几乎完成了,您要做的就是创建一个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放入数组中并使用Promise.all方法来等待它们解决即可。我使用async / await做到了,因为这就是我一直这样做的方式,但是我想您在使用回调进行此操作时将没有问题。

而且代码很凌乱,但这主要是因为我不知道如何使用此文本编辑器,希望您仍然能够理解它👀

© www.soinside.com 2019 - 2024. All rights reserved.