How to invoke firebase Schedule functions locally using pubsub emulator

Solution 1:

Scheduled functions are loaded to the Cloud Functions emulator runtime and are bound to the PubSub emulator topic.

But as @samstern said (https://github.com/firebase/firebase-tools/issues/2034):

you'd have to manually trigger them using a Pub/Sub message.

You can do it like this:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import { PubSub } from '@google-cloud/pubsub';

if (!admin.apps.length) {
  admin.initializeApp();
}

const pubsub = new PubSub({
  apiEndpoint: 'localhost:8085' // Change it to your PubSub emulator address and port
});

setInterval(() => {
  const SCHEDULED_FUNCTION_TOPIC = 'firebase-schedule-yourFunctionName';
  console.log(`Trigger sheduled function via PubSub topic: ${SCHEDULED_FUNCTION_TOPIC}`);
  const msg = await pubsub.topic(SCHEDULED_FUNCTION_TOPIC).publishJSON({
    foo: 'bar',
  }, { attr1: 'value1' });
}, 5 * 60 * 1000); // every 5 minutes

Additional info about this concept (thanks to @kthaas):

  1. https://github.com/firebase/firebase-tools/pull/2011/files#diff-6b2a373d8dc24c4074ee623d433662831cadc7c178373fb957c06bc12c44ba7b
  2. https://github.com/firebase/firebase-tools/pull/2011/files#diff-73f0f0ab73ffbf988f109e0a4c8b3b8a793f30ef33929928a892d605f0f0cc1f

Solution 2:

As you said, you can use firebase shell to run your function once. And in firebase shell, you can use NodeJS commands.

Use setInterval

Inside firebase functions:shell, use setInterval to run your function every 2 minutes.

user@laptop:~$ firebase functions:shell

✔  functions: functions emulator started at http://localhost:5000
i  functions: Loaded functions: myScheduledFunction
firebase > setInterval(() => myScheduledFunction(), 120000)

> this runs every 2 minutes

Single line script

Since version 8.4.3 of firebase-tools, and especially this PR, the pipe solution does not work anymore.

In Bash, you can even pipe the setInterval command to firebase shell

user@laptop:~$ echo "setInterval(() => myScheduledFunction(), 120000)" | firebase functions:shell