Bitbucket Pipelines, Firebase Functions, and Missing Environment Variables: The Real CI/CD Fix

by | May 22, 2025 | Programming, Tech

For developers working with Firebase Functions and modern CI/CD, there are a few hidden corners that aren’t obvious until you stumble over them. We use Bitbucket for some of our development. Yesterday, a routine deployment of a new feature in our internal toolset turned into a fact-finding crusade. If you’re deploying to Firebase Functions via Bitbucket Pipelines, and you’re using the new Firebase environment configuration system, you might encounter a set of errors about missing environment variables. Here’s how we navigated that maze and a few lessons learned for those following a similar path.

Developer struggling with deploying and understanding errors.

Why Does This Happen?

The latest Firebase Functions SDK encourages using environment variables through a defineString or defineSecret interface. The intention is clear: keep secrets out of code, keep config flexible, and make deployments safer and more manageable.
However, many deployment guides assume you’re deploying interactively from a local machine. When you push your code via Bitbucket Pipelines, environment variables are typically injected at the top-level shell—but there’s a catch: if Firebase’s CLI or your deployment process launches sub-processes, or if the env file is not in the right place, your variables can mysteriously disappear, leading to cryptic errors like:

Error: In non-interactive mode but have no value for the following environment variables: ...

This isn’t just a Firebase issue; it’s a pattern that pops up in any “12-factor” app setup, especially when moving to a robust CI/CD pipeline.

Bitbucket Pipelines: Where Do Your Variables Live?


Bitbucket Pipelines lets you set secure variables in the repository settings. These are made available to the pipeline as environment variables for each step. If your pipeline step launches another process or changes directories, you might inadvertently leave these variables behind. On top of that, Firebase’s CLI expects these variables either in the current process or in a dotenv file in a specific directory.

Repository variables in Bitbucket

Here’s the subtlety:
Firebase’s CLI will look for environment files in your function source directory.
 So if your functions live in /functions, that’s where your .env (or .env.staging, .env.production, etc.) needs to go.

The Solution: Write Your Env File Where It Matters

The workaround is simple, but it’s easy to miss: explicitly write a dotenv file into your functions directory as part of your pipeline step, then let Firebase CLI pick it up automatically.
Example Bitbucket Pipelines step:

script:
  - cd functions
  - npm install
  - npm run build:ci
  # Write environment variables to .env.staging (for staging deploy)
  - echo "SOME_API_KEY=$SOME_API_KEY" > .env.staging
  - echo "SOME_API_URL=$SOME_API_URL" >> .env.staging
  - echo "ENABLE_SOMETHING=$ENABLE_SOMETHING" >> .env.staging
  - cd ..
  - GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/your-service-account-key.json firebase deploy --project staging --non-interactiveCode language: YAML (yaml)

Replace the sample variable names with your own, but avoid anything production-critical in your tutorials or examples.

Why Not Just Use Environment Variables?
In theory, you could keep everything in environment variables. In practice, with the way CI/CD pipelines and some CLIs interact, using a dotenv file is safer and more deterministic. Plus, you can keep a .env.example in your repo (minus secrets) as documentation for your team.
When using project-specific deployments, you can create .env.staging, .env.production, and so on. The Firebase CLI will prioritize the most specific file based on your target project.

A Checklist for a Smooth Firebase Functions CI/CD Pipeline

  1. Don’t trust that your CI will pass variables everywhere: Write them explicitly into the directory where your functions live.
  2. Use project-specific dotenv files: This helps avoid cross-contamination between environments.
  3. Keep secrets out of source control: Never commit .env with real secrets; use .env.example for documentation.
  4. Be explicit in your pipeline scripts: Small details, like the working directory, matter more than you’d expect.
  5. Double-check your deploy command: Make sure your environment is set, your credentials are in place, and the right dotenv file is present before calling firebase deploy.

Final Thoughts

It’s the small details in infrastructure that end up eating the most time on a project. While it’s tempting to reach for the “simple” local workflow, spending the extra hour to automate this in CI/CD is always worth it—especially as your team grows, or you onboard new projects.
I hope this helps the next person who gets hit with those mysterious missing environment variable errors from Firebase. If you’ve got further wrinkles, or a more elegant solution,let us know!


Happy deploying.

Related posts