I want to start a new hobby, where I post the solution to something I can’t find 2-3 google away. If I can’t Google and find my solution in one-shot. I’ll write a short tutorial about it. So here comes the first in this blog.
If you want to create an upload image endpoint inside Google Firebase (Cloud functions), then here is one way you can do it.
import * as functions from 'firebase-functions';
import * as Busboy from 'busboy';
import { tmpdir } from 'os';
import { join } from 'path';
import { createWriteStream, unlinkSync } from 'fs';
import * as FileType from 'file-type';
import * as admin from 'firebase-admin';
admin.initializeApp(); // It will automatically authenticate
export const uploadImage = functions.https.onRequest(async (request, response) => {
const busboy = new Busboy({
headers: request.headers,
limits: {
fileSize: 2 * 1024 * 1024, // max image size to 1 MB
files: 1 // Limit to one file upload
}
});
let filepath: string = "";
const _tmpdir = tmpdir();
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
filepath = join(_tmpdir, filename);
const writeStream = createWriteStream(filepath);
file.pipe(writeStream);
});
busboy.on('finish', async () => {
const fileType = await FileType.fromFile(filepath);
console.log(fileType);
if(!fileType || !(fileType.mime === "image/jpeg" || fileType.mime === "image/png")) {
unlinkSync(filepath);
response.status(500).send({
'error': 'Invalid file',
'code': 'invalid_upload_file'
});
return;
}
await admin.storage().bucket().upload(filepath, {
// Support for HTTP requests made with `Accept-Encoding: gzip`
gzip: true,
metadata: {
// Enable long-lived HTTP caching headers
// Use only if the contents of the file will never change
// (If the contents will change, use cacheControl: 'no-cache')
cacheControl: 'public, max-age=31536000',
},
});
response.send({
'status': 'Upload successful'
});
busboy.end(request.rawBody);
});
I’m new to Google Firebase and Cloud functions, so this might not be the best way to do it, but it works
So what we did was
- Process the form data using busboy
- Store the image in a temp directory
- Upload the image using
firebase-admin
storage module
But what about multiple files upload at once?
You can modify this line
limits: {
...
files: 50 // <--- or remove it to allow infinity
}
and instead of replacing filepath
you create an array of file paths instead. After that, process the filepaths
array accordingly in
busboy.on('finish', async () => {
...process the array
});
Top comments (0)