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.
Related
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
I've a use case, where in I want to maintain some rarely changing constants in firebase and load them into my cloud functions project (project-1) when there is a constants.changed config value is set to true. During the next request execution, I'll update my JS file with modified constants and reload the node cache for that file using
delete require.cache[require.resolve('./constants.js')].
Also, here I want to re-set the flag constants.changed to false so that next request won't really do the same thing!. In this way I can avoid hitting firebase continuously in each request for that rarely changing constants document.
I could set this config manually, but I've another system (cloud functions project [project-2]) which actually makes these changes to the constants. Hence I want the cloud function in project-2 to to set the firebase cloud functions config value constants.changed to true.
Am I running after a mirage? is this even possible to achieve. I've checked int the documentation, but seems the Config interface is not exposing such a functionality!
It is not possible to achieve what I said in the question!
Two basic premise is not considered in the above requirement narration.
Cloud functions config when changed, the cloud functions using that config need to be re-deployed to make the changes take effect.
Seems the cloud functions running on the server are in read only file system.
Both the above two limitations makes it impossible to achieve what I've asked for. But it would be a nice to have feature (hot deployments!)
I'm working on the implementation of some Cloud Functions for Firebase and one of these require some configuration to call external providers.
I was able to successfully configure these values using firebase functions:config:set key="value" but I was wondering what are the actors able to read this value.
Is the function the only capable of read it? Should I encrypt "value"? At the end will have to have the key in order to decrypt it.
Thanks
Environment configuration is created exactly for keeping some settings or 3rd-party services keys.
Only your google functions will be able to extract the value on remote environment.
Also you can check those values locally using firebase functions:config:get key command.
To get those variables from the code of your function use this:
const functions = require('firebase-functions');
const someEnvVar = functions.config().key
// where key is name of key you setted before
See more in official docs
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.