Functions shell/emulator unable to load default credentials
See original GitHub issue[REQUIRED] Environment info
firebase-tools: 7.12.1
Platform: Debian on WSL on Windows 10
[REQUIRED] Test case
import * as functions from 'firebase-functions';
const admin = require('firebase-admin').initializeApp(functions.config().firebase);
exports.action1 = functions.https.onCall(() => {
return admin.database().ref('action').push({ 'a': 1 })
});
[REQUIRED] Steps to reproduce
npm run shell
with the above code, execute function action({})
[REQUIRED] Expected behavior
The shell environment should be able to locally simulate the function and access the database, according to the documentation: Cloud Firestore and Realtime Database triggers already have sufficient credentials, and do not require additional setup.
[REQUIRED] Actual behavior
I receive the following message:
@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: "Error fetching access token: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal. Error code: ENOTFOUND".”}
Some digging through the documentation provided me with various different answers, none of which solved my issue. Please note that I would like to locally develop with the same code as the one that I deploy. Some things I found:
-
I tried with and without
functions.config().firebase
but it’s not clear when and if this is required -
Setup Admin Credentials using the export command. I changed the default command to:
"shell": "export GOOGLE_APPLICATION_CREDENTIALS=\"my-owner-key.json\" && tsc --watch --preserveWatchOutput & firebase functions:shell",
According to the (closed) issue #595 for some reason a protect_env
flag sets this environment variable to an empty string. I don’t see the reasoning for this ‘protection’ as the documentation explicitly explains you need to set this variable if you wish to use the shell in an authenticated fashion. PR #1252 added the functionality to disable protect_env
but I couldn’t get the --disable-features
flag working or even find any documentation on it anywhere.
serviceAccount = require('./serviceAccount.json');
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
adminConfig.credential = admin.credential.cert(serviceAccount);
admin.initializeApp(adminConfig);
Somehow injecting the json is supposed to work according to the documentation however this code fails to compile with the following error:
error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
Type 'undefined' is not assignable to type 'string'.
const adminConfig = JSON.parse(process.env.FIREBASE_CONFIG);
It also feels hacky and would not be transferrable to the server as-is as it explicitly depends on a .json
credential file being deployed.
Edit: I found a 4 month old issue on this topic that is still regularly receiving reports of users encountering the same problem: #1708
Issue Analytics
- State:
- Created 4 years ago
- Reactions:5
- Comments:20 (9 by maintainers)
Hmm ok so after some more digging I found out:
functions:shell
but actually anything that uses the emulator (includingemulators:start
)gcloud auth application-default login
but I don’t see why that was necessary …To everyone watching this thread: today we released version
8.5.0
of the CLI which contains big changes for how authentication works in the Functions Emulator.Namely: if you’re logged into the CLI with
firebase login
we will pass those credentials into the emulator as temporaryGOOGLE_APPLICATION_CREDENTIALS
(unless you’re providing your own). This should mean you don’t need to rely ongcloud
for basic authentication anymore.If this causes any problems please file a new issue!