I have a function that starts off with a trigger like this:
exports.generateThumbnail = functions.storage.object().onChange(event => {
How do I test this locally? I've read the local testing docs from Firebase, but can someone give me an example how to trigger this locally, it's a bit confusing at the moment. Thanks!
To test Firebase Cloud Functions locally, you have two options:
The latter only works for HTTPS Functions so it's actually not relevant for your purposes (you're testing a Storage triggered Function).
Let's invoke Cloud Functions Shell from the project's functions
directory:
$ npm i -g firebase-tools@latest
...
$ firebase --version
3.17.3
$ firebase experimental:functions:shell
i functions: Preparing to emulate functions.
✔ functions: generateThumbnail
firebase >
This gives you an interactive shell, where you can directly execute your Functions:
firebase > generateThumbnail()
'Successfully invoked function.'
...
Or any other JavaScript code really:
firebase > console.log(Math.random())
0.17387339404246105
undefined
When testing Functions locally, you won't receive real Firebase Storage events, and as such, you'll have to invoke your Functions with test data.
From the official documentation:
For Storage, Auth, and Crashlytics functions, invoke the local function with the test data that you’d like to see inside of the function. Your test data must follow the corresponding data formats:
- For Cloud Storage: ObjectMetadata
- For Authentication: UserRecord
- For Crashlytics: Issue
Specify only the fields that your code depends on, or none at all if you only want to run the function.
Okay, so next you'll need to create some test data that conform to ObjectMetadata
Create a file testData.json
with the following content in your project's functions
directory. Note the corresponding ObjectMetadata
fields:
{
"bucket": "unique-name-of-your-app.appspot.com",
"contentDisposition": "inline; filename*=utf-8''test.png",
"contentType": "image/png",
"crc32c": "LaOnCg==",
"etag": "CeDut9jz5dgCFAE=",
"generation": "1416567827822212",
"id": "unique-name-of-your-app.appspot.com/test.png/1416567827822212",
"kind": "storage#object",
"md5Hash": "N2rxNWE0ZGRtZmE0Y2M2NDIyOWY5NzIeNzA4YzdizjU=",
"mediaLink": "https: //www.googleapis.com/download/storage/v1/b/unique-name-of-your-app.appspot.com/o/test.png?generation=1416567827822212&alt=media",
"metadata": {
"firebaseStorageDownloadTokens": "1cbc7278-9e5b-4d05-a5de-91a3a067a4bc"
},
"metageneration": "1",
"name": "test.png",
"resourceState": "not_exists",
"selfLink": "https: //www.googleapis.com/storage/v1/b/unique-name-of-your-app.appspot.com/o/test.png",
"size": "168501",
"storageClass": "STANDARD",
"timeCreated": "2018-01-21T20: 33: 47.739Z",
"timeDeleted": "2018-01-21T20: 33: 58.207Z",
"timeStorageClassUpdated": "2018-01-21T20: 33: 47.739Z",
"updated": "2018-01-21T20: 33: 47.739Z"
}
As the documentation says, you won't necessarily need all these fields, use the ones you actually need for your test(s).
Now you can go back to the Cloud Functions Shell and import the test data:
firebase > const testData = require('./testData.json')
undefined
And invoke your Function with the test data as an argument:
firebase > generateThumbnail(testData)
'Successfully invoked function.'
...
To further automate, you can also create a testFunction.js
file with the following content:
const testData = require('./testData.json');
generateThumbnail(testData);
Now, instead of manually typing in all these into the Cloud Functions Shell, you can simply execute it from your OS's shell and redirect the testFunction.js
through standard input:
$ firebase experimental:functions:shell < ./testFunction.js
i functions: Preparing to emulate functions.
✔ functions: generateThumbnail
firebase > const testData = require('./testData.json');
undefined
firebase > generateThumbnail(testData);
'Successfully invoked function.'
...
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With