0

How can I pass different values for the cron so that I can schedule the function at different times in different environments?

Previously I had the cron value hardcoded in the schedule, like:

export const nameFunction = functions
  .region(...regions)
  .runWith({
    timeoutSeconds: 540,
    memory: '128MB',
  })
  .pubsub.schedule("*/5 * * * *")
  .timeZone('Europe/Copenhagen')
  .onRun(async (context) => {

My goal is to change that to a config or secret in order to make it variable accordingly to the environment that it's deployed. Example: Dev: 5 minutes, Staging - 10 minutes, Prod - 1 day.

I've tried a couple of things but it simply doesn't work. This is my latest piece of code.

export const nameFunction = functions
  .region(...regions)
  .runWith({
    timeoutSeconds: 540,
    memory: '128MB',
    secrets: ['CRON'],
  })
  .pubsub.schedule(process.env.CRON as string)
  .timeZone('Europe/Copenhagen')
  .onRun(async (context) => {
Nino Matos
  • 91
  • 9
  • 1
    "Now the real question" - please remove everything before (and including) this sentence. It's really not suitable for Stack Overflow IMO. (Each post on SO should be a single question, and "Does anyone really uses Google Secret Manager" would be off-topic as its own post.) – Jon Skeet May 11 '23 at 07:18
  • Fair enough! It was written in a frustrated way so I will create an off-topic for the first part. – Nino Matos May 11 '23 at 07:55
  • 1
    It's not clear to me how Secret Manager is relevant here... are you trying to put the schedule in Secret Manager? Or something else? (Is this primarily "How do I schedule functions"?) If you read your question back to yourself, is it obvious to you what the goal is, just from what's in the question? – Jon Skeet May 11 '23 at 07:59
  • Previously the function had a hardcoded value for the schedule part: `.pubsub.schedule("*/5 * * * *")` and no secrets inside runWith. The function will run every 5 minutes in all environments. My goal is to change that to a config or secret in order to make it variable accordingly with the environment that it's deployed. Example: Dev: 5 minutes, Staging - 10 minutes, Prod - 1 day. The ideal way would be to do it in a way that i could change dynamically, like if I change the value of the CRON, the periodicity of the function would change. But I don't think it's possible right now in Functions – Nino Matos May 11 '23 at 08:19
  • 1
    Right - all of that should be in the question. (I don't know whether it *is* feasible or not, but making the question clear will make it more likely that you'll get an answer from someone who *does* know.) – Jon Skeet May 11 '23 at 08:25
  • I guess this comments worked as a therapy then because I was almost smashing the keyboard. Thanks anyway! I've made some changes at the initial post. – Nino Matos May 11 '23 at 08:32
  • 1
    It's definitely clearer now. Hopefully someone with more knowledge will be able to help. – Jon Skeet May 11 '23 at 09:51
  • Hi does my posted answer help ? If so then acknowledge if not then we can solve it further. – Rohit Kharche May 18 '23 at 07:08

1 Answers1

1

You can use the following technique to dynamically assign schedule time :

  1. In your Firebase project, set the appropriate secrets or environment variables for each environment. And also define 1 ENV variable in the .env file like dev, staging, prod.

You can set the environment variables by running the following commands:

# Set the environment variables for the development environment
firebase functions:config:set DEV_SCHEDULE_INTERVAL="5"

# Set the environment variables for the staging environment
firebase functions:config:set STAGING_SCHEDULE_INTERVAL="10"

# Set the environment variables for the production environment
#The cron expression */1440 * * * * * means "every 1440 minutes," or "every 24 hours".
firebase functions:config:set PRODUCTION_SCHEDULE_INTERVAL="1440"
  1. Use the appropriate schedule interval based on the environment using some handy switch case :
import * as functions from 'firebase-functions';

const regions = ["us-central1", "europe-west1"];
const getScheduleInterval = (): string => {
  const environment = process.env.FUNCTION_ENV || 'dev';

  switch (environment) {
    case 'staging':
      return `*/${process.env.STAGING_SCHEDULE_INTERVAL || '10'} * * * * *`;
    case 'production':
      return `*/${process.env.PRODUCTION_SCHEDULE_INTERVAL || '1440'} * * * * *`;
    case 'dev':
    default:
      return `*/${process.env.DEV_SCHEDULE_INTERVAL || '5'} * * * * *`;
  }
};

export const nameFunction = functions
  .region(...regions)
  .runWith({
    timeoutSeconds: 540,
    memory: '128MB',
    secrets: ["DEV_SCHEDULE_INTERVAL", 
              "STAGING_SCHEDULE_INTERVAL", 
              "PRODUCTION_SCHEDULE_INTERVAL"]
  })
  .pubsub.schedule(getScheduleInterval()) // dynamically set the schedule interval
  .timeZone('Europe/Copenhagen')
  .onRun(async (context) => {
    // Your function logic here
  });

Secrets set in firebase will be referenceable with process.env inside the function refer the below link.

Reference : Create and use a secret

Rohit Kharche
  • 2,541
  • 1
  • 2
  • 13