I am working on cloud functions especially schedule functions. I need to trigger a function periodically each 5 minutes, but in only test step. I need to run it on pubsub emulator without deploying it.
How to do it?
I tried to use firebase shell, but it triggered only once
exports.scheduledFunctionPlainEnglish =functions.pubsub.schedule('every 2 minutes')
.onRun((context) => {
functions.logger.log("this runs every 2 minutes")
return null;
})
The PubSub emulator still not yet support scheduled functions. But you can use firebase functions:shell and setInterval to simulate scheduler. NOTE: Please ensure you are running the firebase emulator locally, or the shell may call the functions in Production !! Don't exit, then it will run your functions every 60 seconds.
In Cloud Functions for Firebase, scheduling logic resides in your functions code, with no special deploy-time requirements. To create a scheduled function, use functions.pubsub.schedule ('your schedule').onRun ( (context)) .
The Firebase local emulator currently doesn't simulate the actual scheduled functions. The documentation says: I suggest filing a feature request with Firebase support. When you deploy a scheduled function, you are actually using Google Cloud Scheduler behind the scenes. The details are managed for you. As stated in the documentation:
Actually there is a Firebase PubSub emulator. To enable it you need to have the recent CLI installed (it's in 8.2.0 for sure) Create a test script locally to submit PubSub messages into the queue:
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):
As you said, you can use firebase shell to run your function once. And in firebase shell, you can use NodeJS commands.
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
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
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