5
votes

This is an Angular CLI app but that's only slightly relevant.

We have pretty typical environment variables, in this case under either

src/environments/environment.ts

or

src/environments/environment.prod.ts

I only ever import my environment using

import { environment } from 'environments/environment'

But, if I run "ng build", it uses "environment.ts" and if I run "ng build --prod" it uses "environment.prod.ts"

Pure magic.

Love it!

But Firebase Cloud Functions is effectively a separate project with a separate build process, so no matter what it just uses "environment.ts" and so I have to remember to manually switch to importing from "environment.prod.ts" each time I deploy to production?

I'm aware of this: https://firebase.google.com/docs/functions/config-env but I don't see how it solves the above problem. Maybe I'm missing something but it seems to me that I'd still have to switch my variables each time using the even-more-cumbersome terminal command syntax (may as well just add ".prod" to my import).

This is workable, sure, but it eliminates safety and some of the convenience of the environment configuration. Eventually someone is bound to do a production deployment and forget to make that switch... and in our case even an accidental deployment to test server with production variables would be harmful since it would mess up our search indexing.

What am I missing? How can I automate the switching?

AskFirebase

1
If you want to automate something, consider writing scripts to do the work. Or even better, use a CI/CD system to eliminate the possibility of making a mistake by hand. This is what mature development teams will do to minimize error. - Doug Stevenson
That sounds swell. How/where can I write a script for the cloud functions module that will recognize the build environment of the Angular project? Functions behaves essentially as its own project, with its own package.json, etc... TBH, I don't actually know how the Angular CLI project recognizes "--prod" being appended to "ng build" to use a different environment variable. The main project's package.json just has the "build" script, and the angular.json specifies the replacement under "configurations", but that doesn't carry over to functions. - Methodician
I don't know anything about Angular. Your web app would be deployed completely separately from your functions anyway. Your question is very broad though - time to do some research on scripting, then post back here when you're stuck with a more discrete problem. - Doug Stevenson

1 Answers

5
votes

I finally found a way to do this.

It turns out that at any point you can access the project name within functions using the following:

const project = process.env.GCP_PROJECT;

In my case I created an enum for my two main projects as follows:

enum Projects {
    mynametest = 'mynametest',
    mynameprod = 'mynameprod',
}

I imported both environments, giving each an alias as follows:

import { environment as devEnv } from '../../src/environments/environment';
import { environment as prodEnv } from '../../src/environments/environment.prod';

Within the relevant functions I used:

const project = process.env.GCP_PROJECT;
let currentEnv;
if (project === Projects.mynametest) {
    currentEnv = devEnv;
} else if (project === Projects.mynameprod) {
    currentEnv = prodEnv;
} else {
    console.error('No valid environment for <something relevant here>');
    return null;
}
// use "currentEnv.<myVar>" as you would normally use "environment.<myVar>"

If anyone finds a better and/or more terse way about this, please do share!