firebase-admin-python icon indicating copy to clipboard operation
firebase-admin-python copied to clipboard

Using Auth Client with Emulator without Credentials Doesn't Work

Open dgildeh opened this issue 3 years ago • 4 comments

After a lot of debugging, it looks like this is the line that is the bug - instead of catching a google.auth.exceptions.DefaultCredentialsError and passing, its trying to catch an AttributeError:

https://github.com/firebase/firebase-admin-python/blob/5e88d927757e61023e274cd8b00270d899fdf513/firebase_admin/init.py#L260

This is crashing my requests to get a user via a Rest API using the library on a local environment with the emulator running but no local credentials installed/local SDK.

Please make sure tests for using the emulator assume no credentials are on the machine or they will break CI/CD pipelines. Any work arounds before a fix is released appreciated!

dgildeh avatar Feb 16 '22 07:02 dgildeh

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

google-oss-bot avatar Feb 16 '22 07:02 google-oss-bot

Hey @dgildeh could you share a bit more on how you set up your environment? Below is what I tried and it seems to be working for me.

export FIREBASE_AUTH_EMULATOR_HOST="localhost:9099"
firebase emulators:start --only auth --project fake-project-id

lahirumaramba avatar Feb 16 '22 18:02 lahirumaramba

Hi sure:

  1. Firebase SDK container installed with Auth/Firestore emulators running inside
  2. Backend Python service built inside container with no authentication credentials/gcloud SDK inside with Firebase Admin SDK calling the Firebase Emulator successfully (I've setup the environment variables on the container as you specified already)
  3. Both containers running with Docker-Compose locally
  4. Client Python service running locally on desktop (not in container so has access to local gcloud SDK on my machine) calling the backend service via gRPC.

I setup remote debugging on the backend service inside the container, which after stepping through the request I saw it failing at that line above and raised this issue.

If you read the code comment for the method I highlighted, its supposed to fall back to environment variables to get the project-id if it can't get local credentials - but because its catching the wrong exception type - its basically crashing the request each time.

I may try to detect if running in Emulator and do firebase_admin.initialize_app() to set the project ID manually as a work around (haven't tried it yet) but ideally my code should just work without any authentication to use the emulator in local dev/test environments.

What I'm aiming for is dev/test don't require any authentication and just use a local emulator, pushing out via Github actions with tests using the emulator too and no authentication, and in Google Cloud Run (where I'm deploying) it just picks up the instance service account metadata to make calls to Google Identity Platform/FireStore without any code changes so I don't accidentially put authentication workarounds for local development/testing that cause security issues in prod.

When I run pyTest on the backend service running locally with the emulator container, they all pass because I assume it was silently picking up the default credentials using my local gcloud CLI, as soon as I put it inside a container without any credentials it fails.

Hope that helps!

dgildeh avatar Feb 16 '22 19:02 dgildeh

I can confirm if I pass in a default projectID when initializing firebase_admin my backend service now works without raising the exception:

if os.getenv('FIREBASE_AUTH_EMULATOR_HOST', ''):
    fbapp = firebase_admin.initialize_app(options={ "projectId": "demo-firebase" })
else:
    fbapp = firebase_admin.initialize_app()

Please change the except line I highlighted in the issue to DefaultCredentialsError and this bug can be closed. This will also make it work as specified in the method comments above that line.

dgildeh avatar Feb 20 '22 06:02 dgildeh