1

I would like to create a cron job with purely Firebase Functions only.

Below is my code:

const functions = require('firebase-functions');
var admin = require('firebase-admin');

var serviceAccount = require('<private_key_path>');

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: 'https://<project_name>.firebaseio.com'
});


cronJob_2min()

function cronJob_2min() {
    console.log('cronjob started')
    setTimeout(function () {
        testTask1()
        cronJob_2min()
    }, 120000);
}

var testTask1Counter = 0
var testTask1Status = true
function testTask1() {
    if (testTask1Status) {
        testTask1Status = false //flag the task is started to avoid re-trigger again before the task is done
        testTask1Counter++
        console.log('testTask1 Executed: ', testTask1Counter)
        testTask1Status = true //flag the task as completed to let next round trigger execute the function
    }

}

After i deployed it, it work as expected, every 2 minutes it will execute the cronJob_2min() and it will call the testTask1() function. But it only run for approximately 20 minutes because the log only shows the counter until 10.

Seems like the server will go into "sleeping mode" after a certain time.

I understand that running the code in background will cost he CPU quota and i am ok with it.

But i would like to know how to make it always "awake"?

Thank you.

Edit 1

Side note: My cloud function do exported with other onCall functions, but its too long so i didn't put in this post. The code i post on top is actually working, just the console.log inside the cronJob_2min() is categorized to one of my onCall function sendEmail.

Edit 2

Is that even possible to keep it awake by doing in this way?

//Setup the express, middleware, etc... I will skip that code here

router.get('/wakeUp', function (req, res) {
    setTimeout(function () {
        var theUrl = "https://us-central1-<project_name>.cloudfunctions.net/api/wakeUp"
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function () {
            if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
                callback(xmlHttp.responseText);
        }
        xmlHttp.open("GET", theUrl, true); 
        xmlHttp.send(null);

    }, 120000);
    return res.status(200).send('Tata! I am awake! (I suppose)')
})

app.use(router)
exports.api = functions.https.onRequest(app)

Unless Firebase Functions is smart enough to avoid http request from it self, else it suppose will work?

Jerry
  • 1,455
  • 1
  • 18
  • 39

1 Answers1

1

Implementing a reliable cron style job isn't possible with only Cloud Functions. All functions have a maximum configurable timeout of 9 minutes (1 minute default). After the timeout, your function will be shut down with an error in the log.

You're not even defining a proper Cloud Function in the code you're showing, and the effects of that aren't even documented (and effectively unsupported). I'm surprised it's deploying and running anything at all what what you've shown.

Cloud Functions is only meant for short work that reacts to changes in your Firebase products (or HTTP requests). If you want to schedule work, you have to bring your own scheduler tool. There's another question on Stack Overflow that discusses some options.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Based on your feedback and also the given link, i added some opinion on how to keep the server awake in `Edit 2`, but i not sure is that even possible. Please advise. – Jerry Sep 20 '18 at 03:53