为什么我的图像在从 Firebase Functions 上传后没有加载到存储仪表板中?

Why is my image not loading in the Storage dashboard after uploading from Firebase Functions?

我正在使用以下 firebase 函数代码。

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const firestore = admin.firestore();

firestore.settings({timestampsInSnapshots: true});

const cors = require("cors")({ origin: true });
const path = require('path');
const os = require('os');
const fs = require('fs');

// Node.js doesn't have a built-in multipart/form-data parsing library.
// Instead, we can use the 'busboy' library from NPM to parse these requests.
const Busboy = require('busboy');

exports.uploadFile = functions.https.onRequest((req, res) => {
    cors(req, res, () => {

    console.log('Request headers: ' + JSON.stringify(req.headers));
    console.log('Request body: ' + JSON.stringify(req.body));

    if (req.method !== "POST") {
            return res.status(500).json({
                message: "Not allowed"
            });
        }

        const busboy = new Busboy({ headers: req.headers });
        let uploadData = null;

        busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
            console.log('fieldname ' + fieldname + 'file ' + file + ' encoding ' + encoding + ' mimetype ' + mimetype);
            const filepath = path.join(os.tmpdir(), filename);
            uploadData = { file: filepath, type: mimetype };
            file.pipe(fs.createWriteStream(filepath));
        });

        busboy.on("finish", () => {
            console.log('Finished');

            const destBucket = admin.storage().bucket("wairz-d5aee.appspot.com");

            destBucket.upload(uploadData.file, {
                    uploadType: "media",
                    metadata: {
                        metadata: {
                            contentType: uploadData.type
                        }
                    },
                destination: '/Images/myImage.jpg'

            })
                .then(() => {
                    console.log('200!');
                    res.status(200).json({
                        message: "It worked!"
                    });
                })
                .catch(err => {
                    res.status(500).json({
                        error: err
                    });
                });
        });
        busboy.end(req.rawBody);
    });

});

这是我的要求。

这是函数的日志。

Request headers: {"host":"us-central1-wairz-d5aee.cloudfunctions.net","user-agent":"PostmanRuntime/7.20.1","transfer-encoding":"chunked","accept":"*/*","accept-encoding":"gzip, deflate","cache-control":"no-cache","content-type":"multipart/form-data; boundary=--------------------------830355209915480769258810","forwarded":"for=\"67.149.5.133\";proto=https","function-execution-id":"pzmqiu8jmisw","postman-token":"6421769e-df95-494c-a88e-c4cb92885fe1","x-appengine-city":"royal oak","x-appengine-citylatlong":"42.489480,-83.144649","x-appengine-country":"US","x-appengine-default-version-hostname":"ncac955097ca6038f-tp.appspot.com","x-appengine-https":"on","x-appengine-region":"mi","x-appengine-request-log-id":"5dec9cdb00ff072e2cbbdcacd70001737e6e636163393535303937636136303338662d7470000164306565646538376331393663343865373435386434653763616334326336393a3338000100","x-appengine-user-ip":"67.149.5.133","x-cloud-trace-context":"f59ac36f71c2827523171e4a58e540e7/11977574301495828521;o=1","x-forwarded-for":"67.149.5.133","x-forwarded-proto":"https","connection":"close"}

Request body: {"type":"Buffer","data":[45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,56,51,48,51,53,53,50,48,57,57,49,53,52,56,48,55,54,57,50,53,56,56,49,48,13,10,67,111,110,116,101,110,116,45,68,105,115,112,111,115,105,116,105,111,110,58,32,102,111,114,109,45,100,97,116,97,59,32,110,97,109,101,61,34,105,109,97,103,101,34,59,32,102,105,108,101,110,97,109,101,61,34,116,101,115,116,73,109,97,103,101,46,106,112,101,103,34,13,10,67,111,110,116,101,110,116,45,84,121,112,101,58,32,105,109,97,103,101,47,106,112,101,103,13,10,13,10,255,216,255,224,0,16,74,70,73,70,0,1,1,0,0,1,0,1,0,0,255,219,0,132,0,9,6,7,16,15,16,16,16,15,15,15,15,16,15,15,15,14,16,16,13,15,15,15,16,15,15,21,17,22,22,21,17,21,21,24,29,40,32,24,26,37,29,21,21,33,49,33,37,41,43,46,46,46,23,31,51,56,51,45,55,52,45,46,43,1,10,10,10,14,13,14,26,16,16,26,43,31,29,29,43,45,45,45,45,45,43,45,43,43,45,43,43,45,43,45,45,45,45,43,45,45,45,45,45,47,43,45,43,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,255,192,0,17,8,0,184,1,18,3,1,34,0,2,17,1,3,17,1,255,196,0,28,0,0,2,3,1,1,1,1,0,0,0,0,0,0,0,0,0,2,3,0,4,5,1,7,6,8,255,196,0,68,16,0,2,1,2,4,2,6,7,5,4,7,9,0,0,0,0,1,2,0,3,17,4,5,18,33,49,65,19,34,81,97,113,129,6,23,50,83,145,147,210,7,35,66,161,177,51,82,209,225,20,98,115,146,193,194,240,21,22,36,68,114,130,178,226,241,255,196,0,25,1,0,3,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,2,3,1,4,5,255,196,0,45,17,0,3,0,1,3,3,3,2,4,7,0,0,0,0,0,0,0,1,2,17,3,18,33,4,49,65,19,20,97,34,81,50,113,161,177,5,36,129,145,193,225,241,255,218,0,12,3,1,0,2,17,3,17,0,63,0,242,129,12,8,34,24,157,216,56,89,209,12,65,16,196,194,108,32,33,1,4,67,2,2,54,16,16,192,156,81,8,64,70,194,88,96,65,81,24,4,204,18,108,37,17,138,32,168,140,81,52,133,48,212,70,168,128,162,57,4,8,85,12,65,30,130,45,68,114,8,196,42,134,164,122,8,180,18,197,37,154,66,171,35,17,99,149,103,17,99,149,96,38,72,22,16,88,106,176,194,195,38,11,211,57,162,63,76,154,96,5,98,144,10,203,69,98,217,96,97,89,150,44,172,178,194,45,150,105,68,196,17,22,194,60,136,182,19,10,38,33,132,83,8,246,17,76,38,162,169,137,104,182,141,113,20,209,138,32,36,146,72,195,159,20,33,8,34,26,200,158,227,8,67,2,8,134,32,73,132,4,53,16,64,134,4,194,109,132,33,172,16,35,20,67,4,155,58,162,49,68,226,136,192,33,130,52,206,129,24,130,10,136,197,19,9,54,49,68,125,49,20,130,61,4,212,115,219,24,162,61,4,90,136,228,17,142,106,99,169,172,179,76,68,83,89,106,152,152,217,49,200,177,202,32,32,142,81,23,32,194,81,12,9,16,70,233,141,147,0,211,37,161,218,66,32,96,176,151,139,168,150,50,197,46,48,113,3,127,33,51,60,143,183,233,201,81,150,41,132,123,69,176,140,42,43,176,128,194,57,132,91,9,165,81,93,196,75,9,97,196,75,205,69,83,43,188,75,71,188,67,198,43,32,78,206,73,52,115,226,132,53,16,68,53,146,61,198,26,136,106,32,136,106,32,73,134,33,8,34,24,129,38,18,198,44,5,141,88,18,160,150,48,8,43,24,176,33,76,37,17,138,32,136,197,19,25,22,198,32,143,88,164,17,200,38,16,161,169,28,162,41,99,82,49,207,69,220,56,23,151,13,43,111,51,169,153,171,130,112,221,86,236,147,174,6,211,197,112,10,199,44,23,167,164,219,151,40,75,12,139,83,135,134,57,12,178,22,226,85,6,95,193,166,165,240,152,222,16,250,83,185,224,171,56,99,113,9,165,136,137,38,50,100,170,118,182,130,165,199,202,46,191,19,29,135,27,159,9,93,205,201,130,238,59,226,16,166,138,104,211,11,15,68,189,251,163,231,2,68,186,120,69,83,2,170,218,106,182,4,20,70,22,7,172,78,253,135,159,100,202,168,110,111,50,105,51,170,244,107,77,45,222,68,48,149,222,88,121,93,229,80,178,33,226,30,61,226,30,49,105,23,36,25,32,83,7,199,8,193,22,35,22,72,246,152,193,12,64,16,196,9,176,196,37,128,176,196,210,52,49,99,22,44,70,44,48,70,134,172,98,197,172,106,197,100,40,53,17,171,32,160,214,190,147,105,208,38,18,180,208,197,18,222,19,14,106,27,2,1,149,4,117,54,230,54,35,152,129,31,60,150,106,208,106,102,204,45,216,121,31,3,58,178,230,19,30,173,100,174,53,47,239,115,29,241,249,150,82,105,14,146,147,116,180,77,136,117,223,79,141,191,88,187,177,195,11,209,220,183,71,43,245,5,48,71,77,198,252,227,104,83,147,45,199,218,200,254,70,104,58,14,35,129,136,219,79,12,105,210,138,89,144,41,117,133,143,17,254,175,58,148,140,48,188,199,17,45,132,4,2,60,12,92,141,232,238,40,145,105,127,42,171,102,177,224,68,167,138,91,24,120,13,220,70,124,162,90,73,198,178,95,37,204,210,215,7,227,42,81,91,153,119,54,220,2,7,124,167,129,226,102,75,250,74,117,17,252,198,62,229,160,182,70,239,19,41,140,214,198,54,154,126,59,76,154,98,236,38,195,242,47,85,31,84,194,33,225,55,50,252,32,74,96,182,218,184,147,192,95,132,167,130,195,116,149,149,109,178,245,155,248,77,252,99,45,180,105,37,109,118,3,128,183,1,230,98,106,95,132,122,31,195,250,85,151,169,93,151,7,207,230,231,171,117,216,18,7,126,158,95,25,139,85,44,55,154,213,171,235,212,199,128,61,95,229,50,208,26,174,163,123,92,2,64,38,192,158,59,74,233,240,136,245,41,106,86,87,158,197,54,49,14,101,188,106,5,176,28,64,26,172,117,13,124,192,54,23,28,37,23,51,162,121,71,43,135,47,2,220,196,60,99,152,138,134,57,73,64,94,72,50,64,182,15,145,88,197,138,88,197,146,61,138,67,1,134,34,196,49,2,109,6,35,22,40,67,89,164, etc.

fieldname imagefile [object Object] encoding 7bit mimetype image/jpeg

Finished

200!

图片似乎已成功上传到 Firebase 存储,而且看起来尺寸合适。但是,当我尝试在存储仪表板中查看它时,它永远不会加载。为什么会这样?

问题是 firebase 认为您没有签署上传文件。

您应该以独特的方式对上传和生成下载令牌进行签名。 您在名为 firebaseStorageDownloadTokens 的元数据中将 downloadToken 作为 属性 发送。

import { v4 as uuidv4 } from 'uuid'

const uuid = uuidv4()

const blobStream = fileUpload.createWriteStream({
     metadata: {
     contentType: file.mimetype,
        metadata: { firebaseStorageDownloadTokens: uuid }
     }
})
        
// then you link will be 
const url = format(
            `https://firebasestorage.googleapis.com/v0/b/${bucket.name}/o/${fileUpload.name}?token=${uuid}&alt=media`
)