Node-Schedule Module Can't Cron Job Scheduled Long Time
Published: 2021-03-19 19:51:12



I used node-schedule module to cron a job executed only once at particular time. I also use callable function to trigger Cloud Function and to get client-side data. The big trouble is that all things are fine to cron a single task until 15 minutes. But, on the other hand it doesn't do the task scheduled further time more than 15 minutes. What may occur after 15 minutes to cancel task? I used Firebase Quickstart code and I add only schedule-job module into the code. I didn't changed anything other than getting scheduling time values from client-side. I really need help for this issue. The cloud function script is below.

Thank you.

/* eslint-disable max-len */
"use strict";

const functions = require("firebase-functions");
const sanitizer = require("./sanitizer");
const admin = require("firebase-admin");
const schedule = require("node-schedule");
admin.initializeApp();
// [START messageFunctionTrigger]
// Saves a message to the Firebase Realtime Database but sanitizes the text by removing swearwords.
exports.addMessage = functions.https.onCall((data, context) => {
  // [START_EXCLUDE]
  // [START readMessageData]
  // Message text passed from the client.
  const text = data.text;
  // [END readMessageData]
  // [START messageHttpsErrors]
  // Checking attribute.
  if (!(typeof text === "string") || text.length === 0) {
    // Throwing an HttpsError so that the client gets the error details.
    throw new functions.https.HttpsError("invalid-argument", "The function must be called with " +
        "one arguments \"text\" containing the message text to add.");
  }
  // Checking that the user is authenticated.
  if (!context.auth) {
    // Throwing an HttpsError so that the client gets the error details.
    throw new functions.https.HttpsError("failed-precondition", "The function must be called " +
        "while authenticated.");
  }
  // [END messageHttpsErrors]

  // [START authIntegration]
  // Authentication / user information is automatically added to the request.
  const uid = context.auth.uid;
  const name = context.auth.token.name || null;
  const picture = context.auth.token.picture || null;
  const email = context.auth.token.email || null;
  // [END authIntegration]

  // [START returnMessageAsync]
  // Saving the new message to the Realtime Database.

  const dateWithTimeZone = (timeZone, year, month, day, hour, minute, second) => {
    const date = new Date(Date.UTC(year, month, day, hour, minute, second));

    const utcDate = new Date(date.toLocaleString("en-US", {timeZone: "UTC"}));
    const tzDate = new Date(date.toLocaleString("en-US", {timeZone: timeZone}));
    const offset = utcDate.getTime() - tzDate.getTime();

    date.setTime( date.getTime() + offset );

    return date;
  };

  const sanitizedMessage = sanitizer.sanitizeText(text); // Sanitize the message.

  const dataFuture = [uid, name, picture, email, sanitizedMessage];

  new Promise(function() {
    schedule.scheduleJob(dateWithTimeZone("Europe/Istanbul",
        data.year, data.month, data.day, data.hour,
        data.minute, data.second), function(data) {
      const theuid = data[0];
      const thename = data[1];
      const thepicture = data[2];
      const theemail = data[3];
      return admin.database().ref("/messages").push({
        text: data[4],
        author: {theuid, thename, thepicture, theemail},
      }).then(() => {
        console.log("New Message written");
        // Returning the sanitized message to the client.
        return {text: data[4]};
      })
      // [END returnMessageAsync]
          .catch((error) => {
            // Re-throwing the error as an HttpsError so that the client gets the error details.
            throw new functions.https.HttpsError("unknown", error.message, error);
          });
    }.bind(null, dataFuture));

  // [END_EXCLUDE]
  });

  return {text: "done"};
// [END messageFunctionTrigger]
});