Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test firebase triggers locally for storage?

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!

like image 672
Shaun Avatar asked Nov 03 '17 13:11

Shaun


1 Answers

To test Firebase Cloud Functions locally, you have two options:

  • Cloud Functions Shell
  • Firebase CLI

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.

like image 63
chiswicked Avatar answered Sep 21 '22 17:09

chiswicked