Firebase functions emulator requesting external network resource: computeMetadata - firebase

I have the firebase emulator running in a docker container locally for testing. The emulator includes everything I'm using for my app (firestore, auth, functions, storage) so that I can develop and test independently of the production environment.
However, I'm getting these warnings which are making me nervous:
functions: Beginning execution of "myFunction"
⚠ External network resource requested!
- URL: "http://---.---.---.---/computeMetadata/v1/instance"
- Be careful, this may be a production service.
I don't know what that URL is? Does it mean I've misconfigured something somewhere?
I'm also getting these warnings:
⚠ emulators: You are not currently authenticated so some features may not work correctly. Please run firebase login to authenticate the CLI.
⚠ functions: You are not signed in to the Firebase CLI. If you have authorized this machine using gcloud application-default credentials those may be discovered and used to access production services.
⚠ functions: Unable to fetch project Admin SDK configuration, Admin SDK behavior in Cloud Functions emulator may be incorrect.
But I don't think I want to authenticate, right? I don't want to touch anything to do with the live project on production while testing locally. Can I safely ignore these, or is there a good reason to authenticate?

The warnings are indicative that there had some issues while initialization during the setup for emulators .
Make sure that the emulator is installed by the following command: firebase setup:emulators:firestore, for this you can refer Documentation.
Deploy your function in the firebase in order to get recognized. you can refer to the Documentation using firebase deploy --only functions
Also to be sure please check your Firebase json and see if the local host is configured and not the production host,just to be sure.
For further reference you can follow up the stackoverflow thread Docker authentication issueand Firestore emulatorwhere a similar issue has been raised by other users which might be helpful.

Related

GOOGLE_APPLICATION_CREDENTIALS for dummy Firebase project

I'm learning to set up Firebase Emulators correctly to work on my projects and I came up with a problem. I can setup the emulators and make them work locally, however, when trying to access firestore it seems to try to access the real Firestore Instance instead of the emulator.
Right now I'm initializing the app like this (in Cloud Functions)
admin.initializeApp();
const db = admin.firestore();
But when I'm running a function I'm getting:
Failed to initialize and load triggers. This shouldn't happen: Failed to read credentials from file GOOGLE_APPLICATION_CREDENTIALS.json: Error: ENOENT: no such file or directory, open 'GOOGLE_APPLICATION_CREDENTIALS.json'
The thing is that if I use the credentials I generated for my project it will work with the real Firestore instance instead of the emulator.
How should I make credentials for my emulated services?
If you are using Firebase Functions emulator as well then Admin SDK will connect to all the running emulators e.g. if only Auth emulator is running then it'll use the emulator and connect to production for other services like Firestore. You can explicitly set the FIRESTORE_EMULATOR_HOST environment variable and Admin SDKs will use the emulator then.
Checkout the documentation for more information.

Unable to call Firebase function from React.js application

I have a React.js application powered by a number of Firebase functions and real time database standing behind them. It has been working without any issue for the past 2-3 months and now I am getting a warning on the functions logs which says that:
#firebase/database: FIREBASE WARNING: {"code":"app/invalid-credential","message":"Credential implementation provided to initializeApp() via the \"credential\" property failed to fetch a valid Google OAuth2 access token with the following error: \"Failed to parse access token response: Error: Server responded with status 404.\"."}
The way I initialize firebase from my React.js application looks like this:
I have double-checked everything standing behind process.env and it seems to be as expected. The website written in React.js in hosted under the Firebase hosting.
And this is how Firebase functions connect to Admin SDK:
I am not sure what would be the issue here. Nothing has changes in the code base from our side. Not sure if Firebase changed something internally that we need to consider.
What solved the issue for me was to go to the google cloud console (where Firebase functions are also available). Then I opened one of the failing cloud functions and I navigated to
My_Function_Name/Edit/RUNTIME, BUILD AND CONNECTIONS SETTINGS/RUNTIME SERVICE ACCOUNT/
And then I noticed there that for all of my functions it was selected App Engine Default Service Account instead of Firebase Admin SDK. I never explicitly set the runtime to this option. So, when I brought it back to Firebase Admin SDK the error was gone I was able to use the application once again.

Firebase hosting deploy with serviceaccount fails with 403

I'm trying to deploy a Firebase hosted project with a Service Account (that I created myself, not one provided by Google/Firebase as default) via a pipeline (Gitlab, but that shouldn't matter for this issue).
When I run the following command locally (same happens in the pipeline):
GOOGLE_APPLICATION_CREDENTIALS="/path/to/serviceaccount.json" firebase deploy --only hosting
I'm getting the following error:
=== Deploying to 'my-firebase-project'...
i deploying hosting
Error: HTTP Error: 403, The caller does not have permission
The --debug does not provide any more details, other than the 403. I've set the following roles to the serviceaccount:
Firebase Hosting Admin
Firebase Rules Admin
API keys viewer
Deploying the rules (using --only firestore) works without issues. I've read the documentation about the roles of Firebase hosting, but assigning these don't work either.
Does anyone know which roles I'm missing?
Note: a service account is used here to do a deployment, so any firebase login / firebase logout actions won't have any effect. See Login to firebase using gcloud service account for details.
With the help of Firebase support, I was pointed to the Deploying to Firebase page, which provides an enumeration of all required roles. To sum it up here:
Cloud Build Service Account
Firebase Admin
API Keys Admin
I was missing the first one, which resulted in this error. Hope that this'll help others as well!
You have to add the role at the cluster level using oadm policy add-cluster-role-to-user cluster-reader system:serviceaccount:myproject:default

How to run firebase emulators for local development with functions, triggers on remote db?

I'm building a firebase API with cloud functions and want to reach my production Database for local testing.
My problem :
When I launch my two firebase emulator (functions and firestore) with
firebase emulators:start
1- My custom API endpoints run on http://localhost:5001 (this works)
2- My triggers reaches a local dababase on http://localhost:8080 whereas I didn't set FIRESTORE_EMULATOR_HOST=localhost:8080 (I want to reach my production database)
OR
When I launch only my "functions emulator" with
firebase emulators:start --only function
...but my triggers are not reached, probably because of this warning
i functions[userOnCreate]: function ignored because the firestore emulator does not exist or is not running.
On the other side I'm building a reactjs App also with firebase running on localhost:3000
I call my local API from this app with firebase SDK. To reach my emulator, I add the line :
firebase.functions.useFunctionsEmulator('http://localhost:5001');
The local emulators don't work with actual cloud-hosted instances of databases. Everything must be local.
You are always free to file a feature request.
you have to use firebase serve instead for firebase emulators:start

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.

Resources