firebase / firebase-tools

The Firebase Command Line Tools
MIT License
3.97k stars 917 forks source link

Setting Environment Variables at Deployment #5936

Open ganta opened 1 year ago

ganta commented 1 year ago

I want to deploy a project with a Node module on a private registry added as a dependency.

I configured .npmrc following:

//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
@scope:registry=https://npm.pkg.github.com

However, I cannot pass environment variables to the build process with the firebase deploy command.

So the authentication error has occurred in the deployment process.

The official document said, "You can set the $NPM_TOKEN environment variable with the --set-build-env-vars argument to your gcloud functions deploy command." https://cloud.google.com/functions/docs/writing/specifying-dependencies-nodejs#private_modules_from_other_repositories

However, since I am using Firebase, I need to use the firebase command, not the gcloud command.

I want to pass environment variables to the build process in the firebase deploy command as well.

cd-blanche commented 1 year ago

Trying to setup a Shopify Checkout Extension and for the love of god cannot find a way to add environment variables at deployment and I'm stuck at:

Missing Shopify API Key Your app is running without the SHOPIFY_API_KEY environment variable. Please ensure that it is set when running or building your React app.

In their docs, it takes 5 minutes to enter them using Heroku and Fly.io. I'm still a relatively new developer so I've been having a hard time trying to figure out how I can get this to work.

joehan commented 1 year ago

@cd-blanche Could you open a separate issue? I think what you're seeing is different from the original feature request here.

saschTa commented 1 year ago

This also affects us and I think this is a big step backwards in DX terms. Some projects use more complex configurations that include for example bucket names but also other runtime relevant data. With the new defineString functionality we could only use simple strings (obviously) during deployment time. But we would like to keep a unified configuration, that is loaded from a json string.

A feature to load the variables from .env files during deploy time would make that also possible without having to use hundreds of defineString calls. Currently all envs are loaded after function hooks are evaluated which makes nested complex json configurations impossible for run and deploytime.

// in v1 by calling functions.config() to load json in deploy and runtime
// this won't work since .env is not loaded at deploy time so function trigger bucket is undefined
const complexConf = JSON.parse(defineString('SOME_ENV_VARIABLE').value()) as ComplexConfigInterface

exports.myConfiguredFunc = storage({bucket: complexConf.documentPipeline.bucketInbound}).onFinalize(()=>{
const url = complexConf.fancyImageCropperServiceUri
}
dooleyb1 commented 1 year ago

I am also encountering the exact same problem. Getting the below error when I run the command firebase deploy --only functions --set-build-env-vars NPM_TOKEN=${NPM_AUTH_TOKEN}

error: unknown option '--set-build-env-vars'

@ganta did you manage to find a workaround?

ganta commented 1 year ago

@dooleyb1 Unfortunately, the only way is to embed the token directly in the .npmrc and then run the firebase deploy command.

kishieel commented 6 months ago

bump

mustafaekim commented 5 months ago

Our project involves multiple node_modules that all are expected to read their environmental variables from process.env and setup themselves accordinly. However because the environmental variables are only defined within the function body, our libraries cannot be configured properly. Isn't there any workaround for this? If I am not mistaken, there are multiple node libraries that depend on configuration of process.env?

guillaumeprevost commented 3 months ago

Experiencing the same situation as the original issue here.

We have several npm packages published in Github private package repositories. We then have a Firebase functions project that use them as dependencies, and builds & deploy via Github Actions.

The build workflow works well : it uses a github-provided secret token in env variables to fetch these packages. However, in the deploy workflow, the deployment step fails because each firebase function that need to be deployed is rebuilt during the "firebase deploy" command execution, via a separate Google Cloud Build process (i.e. executed outsite the Github action).

From what I understand, it fails with an "Unauthorized" error because Github requires the token to fetch the packages from private repositories.

The --set-build-env-vars argument from gcloud doc cannot be used, because it is not recognized by the firebase deploy command, and there doesn't seem to be any alternative solution or workaround to pass an env variables to the build processes.

We really hope to see this feature as this is important for our use case & I'm sure there are plenty of other cases where an env variable is needed at build time for firebase functions.

msacket commented 1 month ago

I'd like to see this working in the new App Hosting environment to include private npm packages or Fontawesome.

vpusher commented 1 month ago

Definitely need this --set-build-env-vars counterpart in firebase-tools for authenticating against private registries. Otherwise, tokens (from .npmrc file) gets embedded in the cloud function source code, which is not great.

msacket commented 1 month ago

If you're deploying with the new App Hosting, you can use the apphosting.yaml file to set the tokens through the environment using secrets like this:

@fortawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=${FONTAWESOME_NPM_TOKEN}
env:
  - variable: FONTAWESOME_NPM_TOKEN
    secret: FONTAWESOME_NPM_TOKEN

The only downside is that having the .npmrc file inside your project file is it takes precedent over your regular user one, so you have to set variables in your own environment using either your command line or .bashrc like this:

export FONTAWESOME_NPM_TOKEN='REPLACE_WITH_TOKEN'