⏱ Scheduling Firebase Cloud Functions with Cloud Scheduler

Pascal Luther
Jan 13 · 4 min read

I recently came across the use case where I needed to schedule a Firebase Cloud Function on a daily basis. I wanted a function that sends an email to my users via Amazon SES every night. A very common use case I’d say.

Since Firebase does not provide a scheduling functionality for its functions (yet), you need to find some other way to schedule a function. And there is a very easy way offered by Google itself: The Google Cloud Scheduler.

So let’s get started.

I am assuming that you already have a cloud function you call via your app manually (as described here), like the one below:

exports.sendEmail = functions.https.onCall((data, context) => {
// sending the email
})

Now that probably works well for you, but we want to call this function regularly and automatically.

Step 1 — Set up a Cloud Scheduler Job

So let’s hop over to your Google Cloud Platform console (which you can access with the same account you use Firebase) and then go to the Cloud Scheduler here.

Off-Topic:
@CodingDoug from the Firebase team just released an awesome and very insightful article about the relationship between Firebase and Google Cloud Platform, check it out here.

It should look more or less like this:

Google Cloud Platform — Cloud Scheduler

Now create a job with the following settings:

Name: (any name)
Description: (any description)
Frequency: Use https://crontab.guru for calculating the right expression
Frequency: (any timezone)

And now the important part:

Target: Pub/Sub
Topic: (any topic name -> note that down)
Payload: (leave blank)

Alright, so the scheduler is set up and will run at the specified interval and call our topic with the topic name we defined above.

But what the hell is a topic and how does that thing call my cloud function? Well, we are not going into the details of Pub/Sub topics, but we are going to create a topic now and then hook our cloud function up to that topic.

Step 2 — Create a Pub/Sub Topic

Let’s move over to Cloud Pub/Sub in our Google Cloud Platform console with this link: https://console.cloud.google.com/cloudpubsub

Creating a Pub/Sub topic in Google Cloud Console.

Now here we click on “create topic” and then create the topic with the name we specified above in the scheduler job.

All done here, let’s just adjust our cloud function accordingly now.

Step 3 — Hook your Function up to the Topic

In the function above, we wait for the http.onCall event to trigger our function. Now that is nice for manually triggering the function from our app. In our case, however, we want to listen to a pub/sub topic and trigger our function from there.

This is very well described in the Firebase documentation here, but let me show you anyway.

Let’s change our function like this:

exports.sendEmail = functions.pubsub.topic('yourTopicName').onPublish(() => {
// sending the email
})

Make sure you replace ‘yourTopicName’ with the name you specified above. And we’re already done, your function will be called in the interval we specified above. That was easy, right? :-)

Bonus 1: Make Function Available both for Pub/Sub and http.onCall

Nothing easier than that, just write your function like so:

exports.sendEmailPubSub = functions.pubsub.topic('yourTopicName').onPublish(() => {
main()
})
exports.sendEmail = functions.https.onCall((data, context) => {
main()
})
async function main() {
// sending the email
}

This is very simplified, of course you will have to handle asynchronous code with .then(())=>{}) or async/await, depending on how your cloud functions are set up.

Bonus 2: Pricing

So you might be wondering: What does that cost me?

Go here https://cloud.google.com/scheduler/ and scroll down to pricing. As of now you get 3 free jobs a month, and you pay $0.10 for every job after that.

Cloud Scheduler pricing is based on the job. A Cloud Scheduler job defines a single activity scheduled to run at a frequency provided in the definition.

The actual running of a job is called an execution. A job is not billed for individual executions. For instance, if a single job is defined to run for “every day of the month”, then that job is billed $0.1/month and not $3/month for 30 executions of that single job.

Pascal Luther

Written by

Business Analyst for zuehlke.com by day, recreational hobby-coder by night. Currently a big fan of Vue & Nuxt.js and of going serverless with Google Firebase.