2025, Dec 21 13:00

Python Firebase Admin hangs on first Firestore call: emulator environment variables and path fixes

Fix Firebase Admin Python freezing on Firestore: detect [::1]:8081 StatusCode.UNAVAILABLE, clear FIRESTORE_EMULATOR_HOST, and correct invalid document paths.

When a Python service initializes Firebase Admin and silently hangs on the first Firestore call, the culprit is often not networking or credentials, but an unexpected detour to the local Firestore Emulator. The tell is a gRPC error complaining about ipv6 loopback and port 8081, followed by StatusCode.UNAVAILABLE. If you have used the Firebase Emulator Suite before, stale environment configuration can push your Admin SDK away from production without you realizing it.

Minimal example that reproduces the freeze

The following snippet sets up Firebase Admin, creates a Firestore client, and attempts to fetch a document. The identifiers are arbitrary, but the logic mirrors a typical setup.

import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
svc_key = credentials.Certificate("./services.json")
init_opts = {
    "databaseURL": "https://not_revealing_my_url.com"
}
app_ref = firebase_admin.initialize_app(svc_key, init_opts)
db_ref = firestore.client(app_ref)
print(db_ref.document("/").get())

Even with Firestore enabled and a valid service account JSON sitting alongside the script, this can stall indefinitely if the environment points to a local emulator that is not running.

What the error actually means

Interrupting the script and inspecting the stack typically reveals a gRPC rendezvous error. A characteristic signature looks like this:

status = StatusCode.UNAVAILABLE

details = "failed to connect to all addresses; last error: UNKNOWN: ipv6:[::1]:8081: tcp handshaker shutdown"

The loopback address [::1] and port 8081 are default for the Firestore Emulator, not for production Firestore. In practice, this indicates that the Admin SDK is honoring emulator settings from the environment and trying to connect to a local endpoint that is inactive.

Root cause

When either FIRESTORE_EMULATOR_HOST or FIREBASE_FIRESTORE_EMULATOR_ADDRESS is present in your environment (globally, in the shell, or injected by your tooling), the SDK routes all Firestore traffic to the emulator. If the emulator is not running, the client keeps attempting to connect to localhost:[::1]:8081 and never reaches the real Firestore backend. In some setups, remnants of a previous emulator installation can also manifest through PATH configuration, which leads to similarly misleading behavior when the emulator is absent.

How to fix and verify

The quickest way to restore connectivity to production is to remove emulator pointers from the environment, restart the application, and confirm that you are not targeting localhost.

On Linux and macOS, clear the variables like this:

unset FIRESTORE_EMULATOR_HOST
unset FIREBASE_FIRESTORE_EMULATOR_ADDRESS

On Windows PowerShell, use the following:

Remove-Item Env:FIRESTORE_EMULATOR_HOST
Remove-Item Env:FIREBASE_FIRESTORE_EMULATOR_ADDRESS

If your shell profile, IDE run configuration, or a .env file sets these variables, remove them there as well. In cases where an old Firebase Emulator was previously installed, ensuring it is not accidentally picked up via PATH has also resolved the issue in practice. After cleaning the environment, restart the application so the process reads a fresh, emulator-free configuration. The initialize_app call itself is adequate for production; no additional emulator settings are required when you want to talk to the live Firestore service.

A separate pitfall in the sample code

There is also a Firestore path issue in the example. A document path must reference a collection and a document ID. The expression document("/") is not a valid document path and will not return a meaningful result. A more appropriate call specifies both segments, followed by a read of the snapshot and optional conversion to a dictionary.

import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
sa_key = credentials.Certificate("./services.json")
config_args = {
    "databaseURL": "https://not_revealing_my_url.com"
}
app_ctx = firebase_admin.initialize_app(sa_key, config_args)
fs_client = firestore.client(app_ctx)
record = fs_client.document("test_collection/test_document").get()
print(record.to_dict())

This corrected version keeps the same program flow while using a valid document path.

Why this matters

Accidental emulator targeting is a productivity sink and a source of confusing timeouts. Recognizing the [::1]:8081 pattern in the error output saves debugging hours and prevents unnecessary changes to credentials, DNS, or network policies. It also makes environment hygiene part of your team’s development workflow when switching between local emulation and production services.

Takeaways

If Firestore access hangs with StatusCode.UNAVAILABLE and references [::1]:8081, assume the SDK is honoring local emulator settings. Clear FIRESTORE_EMULATOR_HOST and FIREBASE_FIRESTORE_EMULATOR_ADDRESS from your environment, restart the process, and verify that calls no longer target localhost. If an old emulator setup lingers, ensure it is not implicitly selected via PATH. Finally, always use a valid collection/document path when reading from Firestore to avoid unrelated API errors masking the real issue.