I am using the following firebase functions code.
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);
});
});
Here are the logs from the function.
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!
The image seems to successfully get uploaded to Firebase Storage and it looks like it is the right size. However, when I try to view it in the Storage dashboard, it never loads. Why is this happening?
The issue is that firebase thinks that you have not signed the upload file.
You should sign you upload and generate download token in a unique way. You send downloadToken as a property in metadata called firebaseStorageDownloadTokens.
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`
)