I am moving some of my firebase-queue workers to Firebase Functions. I have used process.env.NODE_ENV to set some of the configuration for the workers depending on the environment in which I am running them. Is there a way to set the NODE_ENV for the functions while deploying them. I understand that the recommended way to provide such config options is via firebase.config.set which I have verified works as expected but just wanted to check if there is a way to set the NODE_ENV also. When I try to print out the NODE_ENV inside of a function, it is always set to production.
Following Google's Best practices and reserved environment variables in their documentation
Environment variables that are provided by the environment might change in future runtime versions. As a best practice, we recommend that you do not depend on or modify any environment variables that you have not set explicitly.
Basically don't use NODE_ENV. Use your own environment variables and set them accordingly.
NOTE: This documentations is from Google Cloud Functions. Firebase functions are like a wrapper around google cloud functions. Check this question
There is currently no way to set custom environment variables such as process.env.NODE_ENV. What you want to do can only be done for Google Cloud functions and you need to use the gcloud command-line tool.
https://cloud.google.com/functions/docs/env-var#accessing_environment_variables_at_runtime
Other options
If you are developing specifically for Firebase and need a similar solution, then there are options.
Conditions based on project ID
You can access the project id if you are having test, staging and production projects and want to have different behavior or logging depending on the environment.
process.env.GCLOUD_PROJECT is set to your GCP project ID so you can build logic based on that.
if (process.env.GCLOUD_PROJECT === 'my-production-project') {
// Only in production
} else {
// Do something for the test environments
}
Cloud Function Environment Variables
As you already mentioned there's the cloud functions environment variables also. You can effectively create build pipelines that are configuring your environment configuration upon build/deploy and later access them in your cloud function.
- firebase functions:config:set runtime.env="production" --token $FIREBASE_DEPLOY_KEY
Accessing the configuration is effectively the same as your process.env but can not be accessed outside of the scope of a cloud function (i.e. you can't use it in a global variable declaration).
if (functions.config().runtime.env === 'production') {
// Only in production
} else {
// Do something for the test environments
}
At the time I'm answering this question the Firebase SDK for Cloud Functions offers built-in environment configuration out of the box.
Set environment configuration for your project
$ firebase functions:config:set [values...]
Example
$ firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"
Get environment configuration for your project
$ firebase functions:config:get [path]
Example
const functions = require('firebase-functions')
console.log(functions.config().someservice.id)
NOTE: You must redeploy functions to make the new configuration available.
Related
I used to AWS Amplify Auth for a social login, recently.
and, for social provider setting, I'm trying to use amplify auth override.
docs is here: https://docs.amplify.aws/cli/auth/override/
for security reason, I don't want write the secrets inside override.ts like client id, client secrets, etc.
Is it possible to read environment variables in override.ts?
or any idea?
Amplify CLI retained the information in amplify/backend/amplify-meta.json such as project environment information and others resources information.
I used amplify-meta.json as a module.
There is a StackName with the value of amplify-[PROJECT_NAME]-[ENVIRONMENT_NAME]-[PROECT_NUMBER]. So we can get the environment name by deconstructing the string.
override.ts
export function override(resources: AmplifyAuthCognitoStackTemplate) {
const amplifyMetaJson = require('../../../amplify-meta.json');
const envName = amplifyMetaJson.providers.awscloudformation.StackName.split("-").slice(-2, -1).pop();
console.log("Environment for cloudformation => ", envName);
}
Note: This is the temporary solution of an evil way. It is better to fix the issue.
https://github.com/aws-amplify/amplify-cli/issues/9063
By default, Firebase cloud functions are deployed to the us-central1 region, but I wanted to deploy them to the europe-west2 region.
I assumed that setting the default region via the gcloud cli would mean that if I deleted and redeployed my cloud functions, they would automatically be deployed to the default region that I specified. However that is not the case. Instead, it turns out that I need to explicitly set the region for each function in the code, like this:
export const onDocumentCreated = functions.region('europe-west2').firestore.document('/some/collection/{id}').onCreate(async (snapshot) => {
// some code
});
My question is that if specifying the default region via the gcloud cli doesn't determine what region your functions are deployed to, what is it actually used for?
The gcloud config set command just says:
Default region to use when working with Cloud Functions resources. When a --region flag is required but not provided, the command will fall back to this value, if set. To see valid choices, run gcloud beta functions regions list.
Which doesn't give context around what kinds of operations involve the --region flag or what the flag is used for.
Settings in gcloud don't affect the way the Firebase CLI works. They are completely separate tools. Setting a default region in gcloud only affects the way gcloud itself works.
The only way to set the region for functions is what you're doing right now in your code. This is covered in the documentation.
My Firebase default service account ( xxxx#appspot.gserviceaccount.com ) is deleted and cannot be recovered.
Hence I created different service account and now I have to deploy functions using gcloud CLI using gcloud beta functions deploy FUNCTION_NAME --service-account=NEW_SERVICE_ACCOUNT command.
How do I set firebase config variable using gcloud CLI which I can access via functions.config().
When you use Cloud Function, you can defined environment variable that you can use like this in Node
const val = process.env.KEY
To set this KEY=val into cloud function, you can use the env vars setter parameter
For reusing the Firebase functions.config(), and by looking the source code, it should work like this (I didn't test)
Define a JSON for your config, as described in the retrieve part of the Firebase doc
{
"someservice": {
"key":"THE API KEY",
"id":"THE CLIENT ID"
}
}
Make it inline and store it into a CLoud Functions file format. The key of the environment variable must be FIREBASE_CONFIG. The result must be like this (name it config.yaml for example)
FIREBASE_CONFIG: '{"someservice":{"key":"THE API KEY","id":"THE CLIENT ID"}}'
Add the file env vars to the Cloud Function
gcloud functions deploy --env-vars-file=config.yaml ....
Note: Why using a file?
Great question, because you can also use the --set-env-vars param. 2 problems
First, you need to inline the content and to skip the double quote " character. For this, you can do --set-env-vars=TEST=$(echo "'$(cat config.json | sed -z 's/\n//g')'")
The first solution works ONLY if you haven't comma ,. With comma, the gcloud command is lost and, even if you set your json inline content between simple quote ', it considers it as a new env var definition and fail.
Because I didn't have tested, I'm interested to know if this solution works or not!
I have a project were I set up keys as such.
Live keys
functions:config:set stripe.secret="sk_live_..." stripe.publishable="pk_live_..."
Test keys
functions:config:set stripe.secret="sk_test_..." stripe.publishable="pk_test_..."
The application is in its beta stage but live. So there's a lot more changes still done in code.
So I want to avoid setting the keys each time I want to test out some new feature on localhost.
Is there a way to configure firebase functions, to correspond to different Environments?
When on localhost, it should validate with test keys and with on remote live keys?
There isn't a special per-environment configuration. What you can do instead is use the unique id of the project to determine which settings it should apply. Functions can read the deployed project id out of the process environment with GCP_PROJECT
const project_id = process.env.GCP_PROJECT
The values you should use during development is a matter of opinion - do whatever suits you the best.
I believe you can make a .runtimeconfig.json file in your functions directory, which the emulators will read.
For example, first set your local values with `firebase functions config:set stripe.secret="sk_test_...",
Then, run firebase functions config:get > .runtimeconfig.json
When that file is present, from my experience, your firebase emulators will read from that, and you won't keep overwriting production config variables.
Docs: https://firebase.google.com/docs/functions/local-emulator#set_up_functions_configuration_optional
While I find the Cloud Functions in Firebase fairly convenient, I have troubles figuring out how to configure them in any way. the firebase init generated the firebase.json that contains functions.predeploy property, but are there any other options available? I cannot find any schema for this file.
By default my cloud function is deployed as Node.js 6 application. How do I define that I want to use Node.js 8 which is already supported by the platform? How can I change the amount of used memory? How do I define the environment variables? All of these can be specified through cli commands or from UI, but will be overriden during the next deployment. Isn't there something I could add to my firebase.json that would allow me to specify these values as a permanent thing? Or is it that I actually have to work with the full-blown Google Cloud and the Deployment Manager in order to get it to work?
All of your questions are answered in the documentation.
Set the node version.
Set the version by adding an engines field to the package.json file
that was created in your functions/ directory during initialization.
For example, if you prefer to use only version 8, edit package.json to
add this line:
"engines": {"node": "8"}
Specify other runtime config.
To set memory allocation and timeout in functions source code, use the
runWith parameter introduced in Firebase SDK for Cloud Functions
2.0.0. This runtime option accepts a JSON object conforming to the RuntimeOptions interface, which defines values for timeoutSeconds and
memory. For example, this storage function uses 1GB of memory and
times out after 300 seconds:
const runtimeOpts = { timeoutSeconds: 300, memory: '1GB' }
exports.myStorageFunction = functions
.runWith(runtimeOpts)
.storage
.object()
.onFinalize((object) = > {
// do some complicated things that take a lot of memory and time });
Set environment config.