firebase.json for cloud function configuration? - firebase

My Firebase project uses several different storage buckets used by cloud function storage triggers. Although I can change the default bucket for a particular cloud storage function in the console or using CLI after deploying it, I was wondering if there was a way to configure these settings (bucket, memory limit, zip-deployment location) in firebase.json and pick them up automatically during deploy. Sometimes deployment of the entire project resets the cloud function settings, which causes issues for our users. Thanks!

If you want to configure values to consume in your functions, use environment configuration.
From the CLI:
firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"
Then in a function:
functions.config().someservice.key

Related

How to Firebase cloud function deploy privately

When i use firebase deploy --only functions to deploy cloud functions for firebase, i discover, that this functions are deployed with the authentication flag allUsers.
How can i deploy firebase cloud function with private by default as mentioned here ?
There is no way to set this access control level of Cloud Functions through the Firebase CLI. It currently indeed always sets the access to allow all users. It sounds like a reasonable request to allow control of this though, so I'd file a feature request and possibly a PR on the repo.
For now: if you want to set this access level, you will have to do so in the Cloud console as explained in the Google Cloud documentation on controlling access on a function.

Deploy scheduled function to Firebase Functions

How can I deploy a scheduled function to Google Firebase Functions?
I have created a Service Account named
cron-notifications
My code for the function
exports.notification_email = functions
.region('europe-west1')
.pubsub
.schedule('0 * * * *')
.timeZone('Europe/Stockholm')
.onRun(async (event) => { ... }
When I try to deploy using
$ firebase deploy --only functions:notification_email
I get the error below.
Error: HTTP Error: 400, Location must equal europe-west1 because the App Engine app that is associated with this project is located in europe-west1
I can deploy other functions that are not scheduled to "europe-west1" . I think my project is in europe-west1 (how can I verify?)
I have also tried creating a function named notification_email, located in europe-west1, directly from the GCP Cloud Functions Web UI and then deploying my function - overwriting it - with the same result.
I also tried setting the region using
gcloud config set functions/region europe-west1
as stated in the documentation, with the same result.
My $ gclod config list
[core]
account = myAccount
disable_usage_reporting = True
project = myProject
[functions]
region = europe-west1
Please help me out here! :)
When you are using scheduled functions in Firebase Functions, an App Engine instance is created that is needed for Cloud Scheduler to work. You can read about it here.
When those resources are launched for the scheduler to work, they use the location that has been set by default for resources.
Cloud Functions for Firebase (scheduled functions only) — If you run scheduled functions, Cloud Scheduler requires a Google App Engine app; during its setup you're prompted to select your project's default Google Cloud Platform (GCP) resource location (if it wasn't already selected when setting up another service).
I think that you are getting that error because there is a difference between the default GCP resource location you specified and the function one.
More background:
Important: Cloud Scheduler requires that your project have a Google App Engine (GAE) app; during its setup you're prompted to select your project's default Google Cloud Platform (GCP) resource location. This location will be used for GCP services in your project that require a location setting, specifically, your default Cloud Storage bucket and your Cloud Firestore database.
When setting your project's default GCP resource location, primarily consider where you want to store your data and files and, secondly, where you want to run any triggered functions for Cloud Firestore and Cloud Storage. After you set your project's default GCP resource location, you cannot change it.
Link
If you click on the cogwheel next to project-overview in Firebase you can see where your resources are located.
Hope this helps.

Firebase trigger function ignored due to missing "firebaseauth.googleapis.com emulator"

I have a Firebase function createUser that is triggered by auth.user().onCreate.
Whenever I serve functions locally, it is ignored.
I get the same output when I run firebase serve, firebase serve -only functions,firestore, firebase emulators:start, or firebase emulators:start --only functions,firestore:
⚠ functions: Your GOOGLE_APPLICATION_CREDENTIALS environment variable points to /home/david/Sync/alikely/key.json. Non-emulated services will access production using these credentials. Be careful!
✔ functions[createItem]: http function initialized (http://localhost:5000/alikely-ce1d5/us-central1/createItem).
i functions[createUser]: function ignored because the firebaseauth.googleapis.com emulator does not exist or is not running.
As shown above, I have attempted to follow the instructions to setup admin credentials here: https://firebase.google.com/docs/functions/local-emulator.
I have initialized functions and firestore with firebase init, and my project directory contains a firestore.rules, firestore.indexes.json, and a firebase.json. Are the contents of one of these files to blame?
How can I locally emulate all of my functions for full local development? How can I enable the "firebaseauth.googleapis.com emulator"?
The documentation you linked says:
The Firebase CLI includes a Cloud Functions emulator which can emulate
the following function types:
HTTPS functions
Callable functions
Cloud Firestore functions
Auth functions are currently not supported, just the three types mentioned above.

How can I "admin.initializeApp();" no arguments in local

I am always grateful for your help.
I want to write code admin.initializeApp(); both locally and in production.
When I deploy functions to production with no auguments, it works.
But locally, it requires me to write it like below:
const serviceAccount = require("/home/yhirochick/development/ServiceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://xxxx.firebaseio.com/"
});
In the official documentation it says that configuration is applied automatically when you initialize the Firebase Admin SDK with no arguments
But when I execute the command firebase serve --only functions locally and some calls some requests by postman produce the error below:
[2019-07-22T06:45:26.227Z] #firebase/database: FIREBASE WARNING: Provided
authentication credentials for the app named "[DEFAULT]" are invalid. This
usually indicates your app was not initialized correctly. Make sure the
"credential" property provided to initializeApp() is authorized to access the
specified "databaseURL" and is from the correct project.
I want to know How can I "admin.initializeApp();" no arguments locally.
I have grappled with this also and I don't think the local testing scenario currently is explained very well in the official documentation. But here is a solution:
For your local environment you need to download the firebase projects firebase service account json file (found in firebase console under project settings -> service account) and set an environment variable GOOGLE_APPLICATION_CREDENTIALS to point to the file:
# Linux/MACOS version
export GOOGLE_APPLICATION_CREDENTIALS="[PATH_TO_YOUR_SERVICE_ACCOUNT_FILE]"
Read more here, also on how to do this on Windows
Now you will be able to use admin.initializeApp() (with no arguments) locally.
A possible downside of this approach is that you have to set the environment variable each time you fire up a terminal before you start the firebase emulator, because the variable gets deleted when you end the session.
Automate it...
You could automate the export ... command by bundling it together with the command that fires up the emulator. You could do this by adding an entry to the scripts section of your package.json, e.g.:
"local": "export GOOGLE_APPLICATION_CREDENTIALS='[PATH_TO_YOUR_SERVICE_ACCOUNT_FILE]' && firebase emulators:start --only functions"
Then, in this example, you would only need to type npm run local.
Alternative: provide explicit credentials in local environment only
Look at this example: https://stackoverflow.com/a/47517466/1269280.
It basically use a runtime node environment variable to separate between local and production and then use the explicit way of providing credentials in the local environment only.
This is my preferred way of doing things, as I think it is more portable. It allows me to put the service account file inside my codebase and not deal with its absolute file path.
If you do something like this then remember to to exclude the service account file from your repo! (it contains sensitive info).
Background: difference between production and local service account discovery
The reason that admin.initializeApp() (with no arguments) works out-of-the-box in production is that when you deploy to production, i.e. Firebase Functions, the code ends up in a 'Google managed environment'. In Google managed environments like Cloud Functions, Cloud Run, App Engine.. etc, the admin SDK has access to your applications default service account (the one you downloaded above) and will use that when no credentials are specified.
This is part of Google Clouds Application Default Credentials (ADC) strategy which also applies to firebase functions.
Now, your local environment is not a 'google managed environment' so it doesn't have access to the default service account credentials. To google cloud, your local box is just an external server trying to access your private Firebase ressources. So you need to provide your service account credentials in one of the ways described above.
Before I knew this, I thought that because I was already logged in to firebase via my terminal i.e. firebase login and were able to deploy code to firebase, the firebase emulator would also have the necessary credentials for the firebase admin sdk, but this is not the case.

update Firebase emulator function timeout duration

When emulating firebase functions locally is there a way to change the function timeout from the default 60s?
--idlePruneInterval has been added as an option to the google cloud emulator CLI: https://github.com/GoogleCloudPlatform/cloud-functions-emulator/issues/66
This option doesn't appear to work is not officially supported in either the firebase serve mode:
firebase serve --only functions --idlePruneInterval=5000
or the experimental shell emulation:
firebase experimental:functions:shell --idlePruneInterval=5000
Is there another way around this problem? Perhaps editing a config file?
The Cloud Functions emulator from Firebase is separate from the one provided by the Google Cloud Platform org. The command line parameters from one won't necessarily work on the other.

Resources