How to do scheduling with cloud functions for Firebase

in #firebase6 years ago (edited)

This is a straight forward article on how to get started with running scheduled tasks with #Firebase. There is actually no built in support for you to set up timers or schedules similar to a cron job. But that does not mean that you can't get scheduling into your Firebase project


Klik di sini untuk baca artikel ini dalam bahasa Indonesia

You can leverage integration with Google App Engine, which has a very easy to manage task scheduler and Python is a good choice of language since it's easy to write very compact yet powerful applications.

In this example we'll be sending push notifications from Google App Engine's scheduler to a HTTPS Cloud Function endpoint. And, oh... did I mention that we'll accomplish this in less than 40 lines of code, including configuration files!!!

Firebase o clock
Tik tok let's go

Google App Engine

Make sure that you know the basics behind Google App Engine and how to set up a project. You should be able to copy paste all the code from this article and get it up and running, even if you just skim through the documentation... let me just clarify: skim Google's documentation, read my article with tender love and care ;-)

app.yaml

This file is the main configuration file for you GAE project. The only part that you should change in this file is the SecretApiKeypart on the last row. Replace that with some random string, such as a random GUID makes a pretty good API key. But remember to keep it secret. You will use that same string later to configure your cloud functions.

runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /cron
  script: main.app
  login: admin

env_variables:
  CRON_API_KEY: 'SecretApiKey'

cron.yaml

This file is the cron job configuration. The frequency configuration really reads like natural language. It's not a mistake.

cron:
- description: "Run cron job"
  url: /cron
  schedule: every 30 minutes

main.app

Finally, the good part. This is the only actual code that we have to write to execute regular push notifications to our Firebase project.

The script is fishing out the your Google Cloud Platform project automatically, so it's important that you're targeting a cloud function with the same GCP project id. Otherwise you have to edit the file and replace with the URL of your cloud function.

from google.appengine.api import urlfetch
import webapp2
import urllib
import os

class Sheduler(webapp2.RequestHandler):
    def get(self):
        appId = os.environ.get('GCLOUD_PROJECT', 'n-a')

        try:
            response = urlfetch.fetch(
                url='https://us-central1-' + appId + '.cloudfunctions.net/cronEndpoint',
                payload=urllib.urlencode({'key': os.environ.get('CRON_API_KEY')}),
                method=urlfetch.POST,
                headers={'Content-Type': 'application/x-www-form-urlencoded'})

            self.response.set_status(response.status_code, response.content)

        except urlfetch.Error:
            self.response.set_status(500, 'Caught exception while calling cloud function')


app = webapp2.WSGIApplication([('/cron', Sheduler)], debug=True)

Cloud Function

Now we're actually already outside the scope of the scheduler. So, we've just created a cloud hosted, zero downtime scheduled webhook service that runs absolutely free (free as in gratis)... all in less than 40 lines of code. Give yourself a pat on the back.

The last part is to create a Cloud Function endpoint that consumes the request.

First we need to also configure Firebase with the API key that we created in the GAE configuration.

$ firebase functions:config:set cron.apikey=SecretApiKey

index.ts

Please note that the name of the function cronEndpoint must match the URL that you configured in the Python scheduler above. You can rename this to anything you want as long as you update it in both places.

export const cronEndpoint = functions.https.onRequest((request, response) => {
    if (functions.config().cron.apikey !== request.body.key) {
        response.status(401).send("I'm sorry Dave, I'm afraid I can't do that");
        return;
    }

    response.status(200).send("The time is now.");
});

Finally

That's all folks, if you want to read more about scheduling, then please check out the Firebase blog for how to set up scheduling with pub/sub or my original article on Medium, which was re-written into this article to be more timeless.

You can find all this code in a github repo that I am not really maintaining. But I'm happy and grateful for feedback and comments that can help to improve the article or scripts.

If you want to keep learning about Firebase, then please follow me on Steemit or get your feed tuned in to the #Firebase tag.

Sort:  

Hi! I'm a robot! I noticed that you took your payout as 100% power-up and I just wanted to let you know that right now, you will potentially make a LOT more money if you take the 50/50 option that pays you some SBD. You can read about why this is true here. If you want me to leave you alone, just reply with the word STOP.