Software Development

Firebase Auth Emulator with Python

Last year, Google released Firebase Auth Emulator as a new component in Firebase Emulator. In case you haven’t heard, Firebase Emulator allows you to run/test a bunch of Firebase services in your local machine, namely:

  • Auth
  • Firestore
  • Realtime Database
  • Functions
  • Hosting
  • PubSub

⚠️ Now before you get too hyped, I need to remind you that despite of its awesomeness, Firebase Emulator is still in beta. So you need to expect some limitations and changes. There are some fair amount of documentation on how to use it but I still find some issues. I’m trying to share some of them and the solution/workaround that I found.

My use case is to build an emulator for a system that consist of a Python API server and a web client (email/password authentication). To be specific, I need to:

  • Validate & extract user ID from Firebase Auth Token sent in each secure request
  • Create user programatically so tester can initialize the system easily
  • Delete users programatically to reset the system easily before starting new test

Validate token

One of the limitation that I faced recently is: Python Firebase Admin SDK hasn’t supported Auth Emulator yet. So even if you can generate the firebase token quite easily from the client, it’s a bit tricky to validate it.

The workaround that I found is to let our Python server locally “validate” the Firebase Auth Token with PyJWT. Since we assume Firebase Auth is trusworthy, we just need the validation to just extract the UID from the token (and some other details if available). Finally, we create a mock user to allow the existing code works.

import jwt
from unittest import mock

# get token from request header
payload = jwt.decode(token, options={"verify_signature": False})
user = mock.Mock()
user.uid = payload['user_id']
if 'phone_number' in payload:
	user.phone_number = payload['phone_number']
if 'email' in payload:
	user.email = payload['email']

There is actually an endpoint that we supposed to be able to use to get the user data from the emulator. But for some reason, it doesn’t work. It keeps returning {'kind': 'identitytoolkit#GetAccountInfoResponse'}, even if we pass an invalid code.

Create user programmatically

While you can use the web portal to add new user, sometimes you need to do it programatically. For example when you want to create script that initialize users and maybe some data that refers to their ID. Luckily, it can be easily done using the REST APIs. The only trick is to know what you should put in the authorization header {'Authorization': 'Bearer owner'}. I couldn’t find it anywhere in the doc, but luckily I found it in a Github issue.

import requests

signup_url = 'http://localhost:9099/identitytoolkit.googleapis.com/v1/accounts:signUp'
signup_data = {
    "email": "yohanes@gultom.id",
    "password": "yohanes",
    "phoneNumber": "+6280989999", 
    "displayName": "Yohanes"
}
r = requests.post(signup_url, json=signup_data, headers={'Authorization': 'Bearer owner'})
user_data = r.json()
print(user_data)
# {'kind': 'identitytoolkit#SignupNewUserResponse', 'localId': 'mfSYLlDWhtTzIumnk9iUi4YSbjci', 'displayName': 'Yohanes', 'email': 'yohanes@gultom.id'}

While we are at it, the API to sign in with email/password is working in the same manner too. You can use it to generate auth token programatically

import requests

signin_url = 'http://localhost:9099/identitytoolkit.googleapis.com/v1/accounts:signInWithPassword'
signin_data = {
    "email": "yohanes@gultom.id",
    "password": "yohanes",
}
r = requests.post(signin_url, json=signin_data, headers={'Authorization': 'Bearer owner'})
res = r.json()
token = res['idToken']
print(token)

Delete all users

Delete users API is not available as the part of the actual Firebase Auth server. It is one of the exclusive APIs for emulator. This API itself may not be too useful except when you are creating script for cleaning up data or automated test.

import requests

FIRESTORE_PROJECT_ID = 'firebase-emulator-demo'
delete_users_url = 'http://localhost:9099/emulator/v1/projects/' + FIRESTORE_PROJECT_ID + '/accounts'
r = requests.delete(delete_users_url, headers={'Authorization': 'Bearer owner'})
print(r.json())
# {}

That’s all I have for now. Hopefully it can help anyone dealing with the Firebase Emulator Auth.

Cheers! ?

0 0 votes
Article Rating
yohanes.gultom@gmail.com

Share
Published by
yohanes.gultom@gmail.com

Recent Posts

Get Unverified SSL Certificate Expiry Date with Python

Getting verified SSL information with Python (3.x) is very easy. Code examples for it are…

3 years ago

Spring Data Couchbase 4 Multibuckets in Spring Boot 2

By default, Spring Data Couchbase implements single-bucket configuration. In this default implementation, all POJO (Plain…

3 years ago

Google OIDC token generation/validation

One of the authentication protocol that is supported by most of Google Cloud services is…

4 years ago

Fast geolocation query with PostGIS

If you need to to add a spatial information querying in your application, PostGIS is…

4 years ago

Auto speech-to-text (Indonesian) with AWS Transcribe and Python

Amazon Web Service Transcribe provides API to automatically convert an audio speech file (mp3/wav) into…

5 years ago

Splitting video with ffmpeg and Python

I had a project to build a simple website that split uploaded video into parts…

5 years ago