""" Single shared firebase_admin App instance. backend/firestore_client.py (real Firestore branch) and backend/auth.py (real token verification) both use this instead of each initializing their own — firebase_admin.initialize_app() raises if called twice for the same app name, so this is a real requirement, not just tidiness. Only imported/called when LOCAL_MODE=false or REAL_AUTH_ENABLED=true — never during the test suite (backend/tests/conftest.py forces both off), so tests never need real credentials. """ from __future__ import annotations import json import os import re import firebase_admin from firebase_admin import credentials _app: firebase_admin.App | None = None _PEM_HEAD = "-----BEGIN PRIVATE KEY-----" _PEM_TAIL = "-----END PRIVATE KEY-----" _PEM = re.compile(r"-----BEGIN\s*PRIVATE\s*KEY-----(.*?)-----END\s*PRIVATE\s*KEY-----", re.S) def service_account_info(raw: str) -> dict: """ Reads the key from the text of FIREBASE_SERVICE_ACCOUNT_JSON. Pasting a key into a host's secret box often damages the line breaks inside "private_key" (they become the two characters \\n, or spaces), and the key then cannot be read at all. Repair that here instead of failing. """ text = raw.strip() if len(text) > 1 and text[0] == text[-1] and text[0] in "'\"": text = text[1:-1] info = json.loads(text, strict=False) key = str(info.get("private_key", "")).replace("\\n", "\n") # Rebuild the key from its body. The header may have lost its spaces too # ("-----BEGINPRIVATEKEY-----") when every space was stripped from the pasted text. found = _PEM.search(key) if found: body = "".join(found.group(1).split()) lines = [body[i:i + 64] for i in range(0, len(body), 64)] key = "\n".join([_PEM_HEAD, *lines, _PEM_TAIL]) + "\n" info["private_key"] = key return info def get_app() -> firebase_admin.App: global _app if _app is None: # A host that only offers environment variables (the Hugging Face Space) passes the key's # content in FIREBASE_SERVICE_ACCOUNT_JSON; a developer's machine points at the file. key_json = os.getenv("FIREBASE_SERVICE_ACCOUNT_JSON", "").strip() if key_json: cred = credentials.Certificate(service_account_info(key_json)) else: cred = credentials.Certificate( os.getenv("GOOGLE_APPLICATION_CREDENTIALS", "./secrets/firebase-service-account.dev.json") ) _app = firebase_admin.initialize_app(cred) return _app