Search code examples
javascriptfirebasegoogle-cloud-functions

Firebase functions config won't deploy


I'm trying to deploy a function that uses a firebase config variable based on the environment variable I set before deploying. This works well on staging (a separate project that looks almost identical to production, except for a couple of env vars), but is failing on production with error TypeError: Cannot read property 'env' of undefined pointing to functions.config().app.env (see code below).

If I browse the function online in https://console.cloud.google.com/functions/details/us-central1/<functionName>?project=<projectName> the .runtimeconfig.json file appears to not have picked up the env variable I have set before deploying to production, while it does that perfectly on staging.

If I set app.env to "staging", it works great for my staging environment, and doesn't show any errors. I tried cd-ing into the functions folder to set the env variable, then back out before deploy, but it didn't change a thing. I even tried writing it into .runtimeconfig.json in the functions folder (though that should only be needed for local testing), but that had no effect either.

EDIT: following some more tests it came out that the .runtimeconfig.json I can see when browsing the function code online is generated from what I set locally via CLI to functions config, and is uploaded when I deploy. It appears this copies fine, whenever I update it, onto staging, but does not do the same into production. I just can't figure out why...

My function:

const functions = require('firebase-functions')
// Stripe needs to be set with its key when the library is being required
const stripe = require("stripe")(functions.config().app.env === 'staging' ? functions.config().stripe.key.staging : functions.config().stripe.key.production)
//                                                      ^^^ this is what the error is pointing to

module.exports = functions.https.onCall(async (data, context) => {
    // ... doin' some stripe magic
})

I'm using npm in a shell command line environment:

firebase functions:config:set app.env="production" && firebase deploy -P production --only functions

Output of firebase use:

% firebase use                                                      
Active Project: default (<stagingProjectName>)

Project aliases for <projectFolderPath>:

* default (<stagingProjectName>)
  production (<productionProjectName>)

Run firebase use --add to define a new project alias.

Output of firebase functions:config:get (among other vars):

{
  "app": {
    "env": "production"
  }
}

Solution

  • I resolved this by first swapping to the production project, setting variables, then deploying from there.

    firebase use production
    firebase functions:config:set someservice.key="keyvalue" ...
    firebase deploy --only functions
    

    Even though I did use the -P flag in my deploy command previously (firebase -P production - see question), that did not set the appropriate config values, apparently.

    EDIT: Looks like the reason the config was present on my staging environment was simply because when using the set command I first updated the config values on staging, it being my default environment set up in firebase CLI. Apparently uploading config data is not part of the deploy process, so it has to be done manually. .runtimeconfig.json is just the file the config from the environment can be downloaded into in order to be used with the emulator.