-
-
Save codediodeio/d4cdcfc16f02d369d6943471727c6062 to your computer and use it in GitHub Desktop.
const functions = require('firebase-functions'); | |
const gcs = require('@google-cloud/storage')(); | |
const sharp = require('sharp') | |
const _ = require('lodash'); | |
const path = require('path'); | |
const os = require('os'); | |
exports.generateThumbnail = functions.storage.object('uploads/{imageId}').onChange(event => { | |
const object = event.data; // The Storage object. | |
console.log(object) | |
const fileBucket = object.bucket; // The Storage bucket that contains the file. | |
const filePath = object.name; // File path in the bucket. | |
const contentType = object.contentType; // File content type. | |
const resourceState = object.resourceState; // The resourceState is 'exists' or 'not_exists' (for file/folder deletions). | |
const metageneration = object.metageneration; // Number of times metadata has been generated. New objects have a value of 1. | |
const SIZES = [64, 256, 512]; // Resize target width in pixels | |
if (!contentType.startsWith('image/') || resourceState == 'not_exists') { | |
console.log('This is not an image.'); | |
return; | |
} | |
if (_.includes(filePath, '_thumb')) { | |
console.log('already processed image'); | |
return; | |
} | |
const fileName = filePath.split('/').pop(); | |
const bucket = gcs.bucket(fileBucket); | |
const tempFilePath = path.join(os.tmpdir(), fileName); | |
return bucket.file(filePath).download({ | |
destination: tempFilePath | |
}).then(() => { | |
_.each(SIZES, (size) => { | |
let newFileName = `${fileName}_${size}_thumb.png` | |
let newFileTemp = path.join(os.tmpdir(), newFileName); | |
let newFilePath = `thumbs/${newFileName}` | |
sharp(tempFilePath) | |
.resize(size, null) | |
.toFile(newFileTemp, (err, info) => { | |
bucket.upload(newFileTemp, { | |
destination: newFilePath | |
}); | |
}); | |
}) | |
}) | |
}) |
{ | |
"name": "functions", | |
"description": "Cloud Functions for Firebase", | |
"dependencies": { | |
"@google-cloud/storage": "^0.4.0", | |
"firebase-admin": "^4.1.2", | |
"firebase-functions": "^0.5", | |
"lodash": "^4.17.4", | |
"request-promise": "^2.0.0", | |
"sharp": "^0.18.1" | |
}, | |
"private": true | |
} |
I'm trying to use your example but to generate thumbnails inside Firebase Storage. I am not restricting to the uploads/ folder as I want it in different folder ({user}/avatar/{imageId}) in my case. I am getting an error in the Firebase functions log ApiError: Forbidden at new util.ApiError (/user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:107:10)
Do I have to add a certificate as mentioned here?
cloud function with sharp , it takes around 8-10 seconds to generate a single thumbnail from a single image file . tell me this is normal .
onChange()
is now deprecated. you should change it to onFinalize()
cloud function with sharp , it takes around 8-10 seconds to generate a single thumbnail from a single image file . tell me this is normal .
I'm having the same issue.
TypeError: gcs.bucket is not a function
at exports.generateThumbnail.functions.storage.object.onFinalize (/user_code/index.js:33:22)
at cloudFunctionNewSignature (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:105:23)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:135:20)
at /var/tmp/worker/worker.js:769:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
UPDATE 2020:
This still works, you have to change some code:
1 . Change
const gcs = require('@google-cloud/storage')();
to
const { Storage } = require('@google-cloud/storage');
const gcs = new Storage()
-
onChange()
is now deprecated. Change it toonFinalize()
. -
If you are using
"fs-extra": "^9.0.0"
, downgrade it to version8.1.0
. Why?v9.0.0
requires node version >=10
it seems, whereas cloud functions are still stable only for nodev8
.
thank you very much... this is a great example! very useful