无法使用JSZip使用Firebase Cloud Functions处理文件

时间:2018-11-03 21:06:47

标签: node.js firebase zip google-cloud-functions

我一直在尝试编写基于Sharp的图像处理引擎。主要思想是将图像作为多部分数据,对其进行格式化,然后将结果作为zip文件返回。下面的代码在我的本地计算机上似乎运行良好,但是一旦将其部署到Firebase,返回的zip文件将为空。可能是什么原因?

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';

const os = require('os');
const fs = require('fs');
const Busboy = require('busboy');
const sharp = require('sharp');
const path = require('path');
const JSZip = require('jszip');

admin.initializeApp();

exports.processImage = functions.https.onRequest((req, res) => {
    if (req.method === 'POST') {
        const busboy = new Busboy({ headers: req.headers });
        const tmpdir = os.tmpdir();
        console.log('Writing files to tmpdir:', tmpdir);

        const uploads = {};
        const fileWrites = [];

        const zip = new JSZip();
        let index = 1;

        busboy.on('file', (fieldname, file, filename) => {
            console.log(`Processed file ${filename}`);
            const filepath = path.join(tmpdir, filename);
            uploads[fieldname] = filepath;

            const writeStream = fs.createWriteStream(filepath);
            const sharpStream = sharp()
                .resize(480, 480)
                .extend({
                    top: 16,
                    bottom: 16,
                    left: 16,
                    right: 16,
                    background: { r: 0, g: 0, b: 0, alpha: 0 }
                })
                .webp({ quality: 50 });

            file.pipe(sharpStream).pipe(writeStream);

            sharpStream.on('data', function(data) {
                console.log('Processing', data.length, 'bytes');
            });

            const promise = new Promise((resolve, reject) => {
                writeStream.on('finish', resolve);
                writeStream.on('error', reject);
            });
            fileWrites.push(promise);
        });

        // Triggered once all uploaded files are processed by Busboy.
        // We still need to wait for the disk writes (saves) to complete.
        busboy.on('finish', () => {
            Promise.all(fileWrites)
                .then(() => {

                    for(const file in uploads) {
                        const filename = uploads[file];
                        let reader = fs.createReadStream(filename);
                        zip.file(`image${index++}.webp`, reader);
                        console.log(`${filename} written`);

                    }
                    let zipName = path.join(tmpdir, 'response.zip');
                    zip.generateNodeStream({ type: 'nodebuffer', streamFiles: true })
                        .pipe(fs.createWriteStream(zipName))
                        .on('finish', function () {
                            res.download(zipName);
                        });
                })
                .catch(err => {
                    console.error(err);
                    res.status(500).end();
                });
        });
        req.pipe(busboy);
    } else {
        // Return a "method not allowed" error
        res.status(405).end();
    }
});

0 个答案:

没有答案