Closed imarian97 closed 4 years ago
Also running into this issue after trying to use the admin SDK as mentioned by @yuchenshi here: https://github.com/firebase/firebase-tools/issues/2749#issuecomment-718141997
One thing I did notice as well (likely separate ticket but maybe could be an easier workaround?). In @firebase/rules-unit-testing
you can call initializeAdminApp
and get what is suppose to be an admin app, but it's Auth
doesn't have all the same methods as firebase-admin
's Auth
, namely createUser()
which is what I specifically was trying to use to create users with specific uid
's for testing
@imarian97 you mentioned: Firebase SDK version: v8.14.0
. Note that the emulator support is only available on latest version (v9.3.0) of the SDK.
@imarian97 you mentioned:
Firebase SDK version: v8.14.0
. Note that the emulator support is only available on latest version (v9.3.0) of the SDK.
Sorry! I have confused firebase-tools with firebase-admin-node. So, to clarify, I'm using the latest versions at the moment of writing and these versions are:
@IsaiahByDayah On your side comment on rules testing and initializeAdminApp
: I think it's a completely different abstraction from the admin client, only meant for bypassing rules restrictions. Anyways, out of scope of this issue.
Haha, that would explain things wouldn't it 😅. My bad. I guess I just saw "admin" and made assumptions
@IsaiahByDayah ok there's a lot going on here so I have some questions.
Error: Credential implementation provided to initializeApp()
, is this from code running within the Functions emulator? A script running elsewhere? Do you have to do anything besides 'emulators:start` to trigger this error?FIREBASE_TOKEN
environment variable set, does the behavior change with/without that?@IsaiahByDayah ok there's a lot going on here so I have some questions.
- Where do you get this error
Error: Credential implementation provided to initializeApp()
, is this from code running within the Functions emulator? A script running elsewhere? Do you have to do anything besides 'emulators:start` to trigger this error?- It seems like you have the
FIREBASE_TOKEN
environment variable set, does the behavior change with/without that?- Is there a simpler way I could reproduce this behavior? Are you able to get this to happen outside of docker / docker compose?
Hi, Considering the questions I suppose they are also addressed to me so:
I was able to reproduce the same issue in my host machine (running windows) so, it is not docker related. To reproduce the issue, follow the steps in the initial comment. I will rewrite them here in a simpler form:
Assuming you have the specified versions of node, npm and firebase-tools:
npm init -y
in the foldernpm i firebase-admin
in the folderfirebase.json
file in the folder with the content from the initial comment.firebaserc
file in the folder with the content from the initial commentindex.js
file with the following content:
// The test script make sure the FIREBASE_AUTH_EMULATOR_HOST environment var is set
const process=require("process")
process.env.FIREBASE_AUTH_EMULATOR_HOST = "localhost:9099";
var admin = require('firebase-admin');
admin.initializeApp({ projectId: 'local' })
admin.auth().createUser({});
7. Run `node index.js`
So I think this is working as intended, although I'd like to do some experiments myself to try. Setting the FIREBASE_AUTH_EMULATOR_HOST
doesn't really change how firebase.initializeApp()
works, since that initializes things for much more than Auth. And initializeApp()
needs to be able to find a credential from somewhere. Some ways it can find a credential:
credential
param with projectId
GOOGLE_APPLICATION_CREDENTIALS
env var at a service account JSON file, thus authorizing as a service account.gcloud auth application-default
login to put user credentials on your machine, thus authorizing as yourself.Now we try to hide this from you in a few cases:
initializeApp()
inside Google Cloud, like in a Cloud Function or on App Engine or on Compute Engine, we can automatically discover the necessary credentials due to the trusted environment.initializeApp()
inside the Cloud Functions Emulator, we simulate (1) by morphing your firebase login
credentials into something the Admin SDK recognizes.So when running a script in a completely unauthorized docker container, I'd expect this error.
So I think this is working as intended, although I'd like to do some experiments myself to try. Setting the
FIREBASE_AUTH_EMULATOR_HOST
doesn't really change howfirebase.initializeApp()
works, since that initializes things for much more than Auth. AndinitializeApp()
needs to be able to find a credential from somewhere. Some ways it can find a credential:
- You could manually pass a
credential
param withprojectId
- You can point the
GOOGLE_APPLICATION_CREDENTIALS
env var at a service account JSON file, thus authorizing as a service account.- You can use
gcloud auth application-default
login to put user credentials on your machine, thus authorizing as yourself.Now we try to hide this from you in a few cases:
- When you run
initializeApp()
inside Google Cloud, like in a Cloud Function or on App Engine or on Compute Engine, we can automatically discover the necessary credentials due to the trusted environment.- When you run
initializeApp()
inside the Cloud Functions Emulator, we simulate (1) by morphing yourfirebase login
credentials into something the Admin SDK recognizes.So when running a script in a completely unauthorized docker container, I'd expect this error.
I forgot to mention an important step but I suppose you already noticed it. The step was to remove or rename the application_default_credentials.json
file which on Windows is located in %appdata%\gcloud
I understand that the initializeApp() needs the credentials but I don't really like to have to provide as a requirement a service account or some other form of credential to my CI/CD pipeline or, in my case, (at least in this stage of the development) to the local development environment, as long as I'm using only the emulators. For Firestore and RTDB emulators, based on my experience, the credentials are not required and I feel like the firebase-admin code can be updated (I have not spent enough time on it to understand how) to also not require the credentials for Auth Emulator.
I don't really have a problem with the credentials but I can't "fit the moment where you generate/obtain the credentials". For the CI/CD I know there are some ways to store a secret (the service account) and then retrieve it but that's extra work and configs considering that only emulators are used. But, for the local development scenario, it is even worse. The ideal scenario for local development which I managed to achieve using the method described in the first comment is to have any developer of my team clone the repo and immediately start working on code (because I've containerized both the dev env and the Firebase Emulators so, everything is configured and starts automatically and the developer does not have to do anything). In this scenario, obtaining the credentials can be a bit annoying considering that including the service account in the repo is not a good practice and the developer might not even have access to a GCP/Firebase project (extremely possible for public projects)
I hope the scenarios and my issue are a bit clear now and I hope to find together (or, maybe, it already exists but I'm missing it) a good solution for completely local development and easy to use CI/CD.
Facing a similar issues here. Admin SDK cannot be used with the Auth emulator without providing valid application credentials.
The particular use case for me is a using the Admin SDK to seed/reset the emulators in a script. And while Admin SDK can successfully interact with the Firestore emulator without any application credentials, the Auth part of the Admin SDK requires application credentials with the Auth emulator.
I am also running into this issue. The documentation for the auth emulator recommends writing a script to create users, but I am not able to get admin-firebase to work this way unless I provide it with credentials to a real environment.
@dbanisimov @nVitius thanks for your feedback! According to @yuchenshi we may be able to fix this by lazily requiring credentials in firebase-admin-node
when using Auth with the emulator.
This is fixed and released in version 9.4.0
of firebase-admin
[READ] Step 1: Are you in the right place?
[REQUIRED] Step 2: Describe your environment
[REQUIRED] Step 3: Describe the problem
If the 'application_default_credentials.json' is not present in the gcloud config path I get the error from below when I try to call any auth method even though the emulator is started, the FIREBASE_AUTH_EMULATOR_HOST env var is correctly set and the initializeApp is correctly called.
Based on my research this problem comes from the getApplicationDefault function inside the src/credential/credential-internal.ts file. I solved this by running
gcloud auth application-default login
(found on internet, don't know exactly what it does) which generated a valid application_default_credentials.json fileI don't completely understand the underlying mechanisms but I think this behaviour is not great for my use case which is probably very similar with a CI/CD pipeline use case. Also, there's nothing mentioned in the Firebase Auth emulator about this and I really like to be able to run all emulators without a real project but, doing this gcloud config makes me worried not to interact by mistake with the real gcloud project.
Steps to reproduce:
Relevant Code:
I'm running a dev environment using the VSCode .devcontainer feature using the following files:
main.Dockerfile
firebase_emulator.Dockerfile
docker-compose.yml
devcontainer.json
firebase.json
.firebaserc
The minimal code required is to call some auth function using the firebase-admin package. For example: