Initializing Python firestore.AsyncClient

457 views
Skip to first unread message

Alan deLespinasse

unread,
Apr 6, 2022, 4:26:40 PM4/6/22
to Firebase Google Group
Hi, I've been working on a Python backend that uses the Firestore async client. It's not running on Google Cloud, so I need to give it credentials. The documentation says to do it this way:

import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore

# Use a service account
cred = credentials.Certificate('path/to/serviceAccount.json')
firebase_admin.initialize_app(cred)

db = firestore.AsyncClient()

I don't actually have a the certificate in a file; it's in an environment variable, which I have to parse with json.loads(), but that part works fine. I know from experience that you can just pass the credentials to credentials.Certificate() as a dict rather than giving it a file name.

Firestore actually worked fine on my local machine, but it turns out that it was because I had GOOGLE_APPLICATION_CREDENTIALS set in my environment, with a certificate file where it was pointing to. When we deployed it to our production environment, it failed with an error like:

google.auth.exceptions.DefaultCredentialsError: Could not automatically determine credentials. Please set GOOGLE_APPLICATION_CREDENTIALS or explicitly create credentials and re-run the application. For more information, please see https://cloud.google.com/docs/authentication/getting-started

It turns out that firestore.AsyncClient() doesn't actually use whatever credentials you gave to firebase_admin.initialize_app(). You have to give the credentials directly to firestore.AsyncClient(), and also tell it the project name. And the credentials have to be created in a completely different way. This is what I ended up with:

from firebase_admin import firestore
from google.oauth2 import service_account

def get_firestore(firebase_cert: str):
    json_acct_info = json.loads(firebase_cert)
    credentials = service_account.Credentials.from_service_account_info(json_acct_info)
    firestore_db = firestore.AsyncClient(
        project=json_acct_info['project_id'],
        credentials=credentials,
    )
    return firebase_db

It doesn't seem to be necessary to call firebase_admin.initialize_app() at all.

So, is the documentation wrong, or is this a bug in the Python admin client? Or am I missing something else?

(Figuring out how to create that credential object was especially hard; nothing in the Firestore documentation seemed to suggest anything like that. Finally when I was trying something else, I got an error message that pointed me to this page.)

Alan deLespinasse

unread,
Apr 6, 2022, 5:43:41 PM4/6/22
to Firebase Google Group
I probably should have led with the most important thing: The sample code in the documentation seems to be wrong. Or else there's a bug in the firebase_admin.firestore client that makes it not work.
Reply all
Reply to author
Forward
0 new messages