Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Database SDK tries to access credential even when FIREBASE_DATABASE_EMULATOR_HOST is set #3144

Closed
filipesilva opened this issue May 26, 2020 · 12 comments · Fixed by #3228 or #3415
Closed
Assignees

Comments

@filipesilva
Copy link

[REQUIRED] Environment info

firebase-tools: 8.4.0

Platform: Windows

[REQUIRED] Test case

I have a test case with minimal cloud function code and emulator at https://github.com/filipesilva/firebase-emulator-credentials.

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

exports.helloWorld = functions.https.onRequest(async (request, response) => {
  const db = admin.database();
  const ref = await db.ref('auth-test').set({
    date: new Date().toISOString()
  });
  response.send(`Added: ${ref.id}`);
});

[REQUIRED] Steps to reproduce

git clone https://github.com/filipesilva/firebase-emulator-credentials
cd firebase-emulator-credentials
yarn
yarn firebase logout
yarn emulators
# open http://localhost:5001/emulator-test-1/us-central1/helloWorld in the browser

You should see the following error log in the console:

kamik@RED-X1C6 MINGW64 /d/sandbox/firebase-emulator-credentials
$ yarn emulators
yarn run v1.21.1
$ firebase emulators:start
!  emulators: You are not currently authenticated so some features may not work correctly. Please run firebase login to authenticate the CLI.
i  emulators: Starting emulators: functions, database
!  Your requested "node" version "8" doesn't match your global version "12"
i  database: Database Emulator logging to database-debug.log
!  hosting: The hosting emulator is configured but there is no hosting configuration. Have you run firebase init hosting?
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "D:\sandbox\firebase-emulator-credentials\functions" for Cloud Functions...
+  functions[helloWorld]: http function initialized (http://localhost:5001/emulator-test-1/us-central1/helloWorld).

┌───────────────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! View status and logs at http://localhost:4000 │
└───────────────────────────────────────────────────────────────────────┘

┌───────────┬────────────────┬─────────────────────────────────┐
│ Emulator  │ Host:Port      │ View in Emulator UI             │
├───────────┼────────────────┼─────────────────────────────────┤
│ Functions │ localhost:5001 │ http://localhost:4000/functions │
├───────────┼────────────────┼─────────────────────────────────┤
│ Database  │ localhost:9000 │ http://localhost:4000/database  │
└───────────┴────────────────┴─────────────────────────────────┘
  Other reserved ports: 4400, 4500

Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.

i  functions: Beginning execution of "helloWorld"
>  [2020-05-26T15:20:21.433Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:22.307Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:23.270Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:24.471Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:26.454Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:28.169Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:30.516Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:33.439Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:38.337Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:39.686Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:48.691Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:20:51.557Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
>  [2020-05-26T15:21:05.098Z]  @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 E
NOTFOUND metadata.google.internal. Error code: ENOTFOUND\"."}
!  functions: Your function timed out after ~60s. To configure this timeout, see
      https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation.
>  D:\sandbox\firebase-emulator-credentials\node_modules\firebase-tools\lib\emulator\functionsEmulatorRuntime.js:619
>                  throw new Error("Function timed out.");
>                  ^
>
>  Error: Function timed out.
>      at Timeout._onTimeout (D:\sandbox\firebase-emulator-credentials\node_modules\firebase-tools\lib\emulator\functionsEmulatorRuntime.js:619:23)
>      at listOnTimeout (internal/timers.js:531:17)
>      at processTimers (internal/timers.js:475:7)

[REQUIRED] Expected behavior

The emulated cloud function call should be successful even though there are no credentials.

[REQUIRED] Actual behavior

The emulated cloud function errors out.

Extra details:

This is a followup from @samtstern's comment on firebase/firebase-tools#1940 (comment).

It's currently not possible to use firebase-admin with the emulators without credentials obtained via https://cloud.google.com/docs/authentication/getting-started.

This use case is especially relevant for CI, where there is no user to login and no credentials should be provided, especially on CI test runners for open-source projects that may receive PRs from forks and which to test them.

@samtstern
Copy link
Contributor

@filipesilva thanks for filing this! I can see the issue clearly now.

The problem is that admin.initializeApp() from firebase-admin doesn't know how to continue without a credential. So it's going in circles.

We need some way to prevent that from happening when inside the emulator.

@samtstern samtstern self-assigned this May 26, 2020
@filipesilva
Copy link
Author

Oh that's interesting, I thought that the emulator somehow added credentials there. Or at any rate something similar happened in firebase-tools@7.12.1, because if you go back to that version this exemple throws no errors.

(it actually throws an error because I still had some leftover code from your firestore example but I've pushed a fix for that now :D)

@samtstern
Copy link
Contributor

@filipesilva looks like this is actually Realtime Database specific, I wrote these two functions:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

exports.helloDatabase = functions.https.onRequest(async (request, response) => {
  const db = admin.database();
  await db.ref('/foo/bar').set({
    date: new Date().toISOString()
  })
  response.send("Hello from Firebase!");
});

exports.helloFirestore = functions.https.onRequest(async (request, response) => {
  const db = admin.firestore();
  await db.doc('/foo/bar').set({
    date: new Date().toISOString()
  })
  response.send("Hello from Firebase!");
 });

I ran all three emulators. helloFirestore worked perfectly, helloDatabase gave the error you described.

@filipesilva
Copy link
Author

Very interesting, so that's why it wasn't very obvious!

@samtstern samtstern changed the title Cannot run firebase-admin in emulator without credentials May 26, 2020
@samtstern samtstern assigned avolkovi and unassigned samtstern May 26, 2020
@samtstern
Copy link
Contributor

Re-assigning to @avolkovi who is on call this week, this may be something we want to transfer over to firebase-js-sdk.

@avolkovi avolkovi transferred this issue from firebase/firebase-tools Jun 1, 2020
@google-oss-bot
Copy link
Contributor

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@avolkovi
Copy link
Contributor

avolkovi commented Jun 1, 2020

reassigning to @schmidt-sebastian since this will require changing the RTDB SDK

@filipesilva
Copy link
Author

@schmidt-sebastian heya, apologies for bugging you about this, but have you had time to look at it? It's still blocking us from updating the emulators since then the CI will break.

@schmidt-sebastian
Copy link
Contributor

I haven't yet. I will try to get to this this week.

@filipesilva
Copy link
Author

Thanks for taking the time @schmidt-sebastian. If there's anything I can do to help, or things you'd like me to test, let me know.

@filipesilva
Copy link
Author

Hi all, just wanted to mention that I've just tried updating and I can confirm it unblocks us, cheers!

It's still possible to get an old version of RTDB while installing firebase-admin@9.0.0 since it's dependency is set as "@firebase/database": "^0.6.0", but I think this fix was only released on "@firebase/database@0.6.8".

Clearing yarn.lock/package.lock can trigger an update, as can using the resolutions field in package.json if using yarn.

Thanks for all the work in getting this in!

@samtstern
Copy link
Contributor

@filipesilva thank you for confirming that this works!

@firebase firebase locked and limited conversation to collaborators Aug 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.