| | """ |
| | Firebase Authentication utilities. |
| | """ |
| | import os |
| | import json |
| | import firebase_admin |
| | from firebase_admin import auth, credentials |
| | from fastapi import HTTPException |
| |
|
| | |
| | _firebase_initialized = False |
| |
|
| | def initialize_firebase(): |
| | """Initialize Firebase Admin SDK.""" |
| | global _firebase_initialized |
| | |
| | if _firebase_initialized: |
| | return |
| | |
| | if not firebase_admin._apps: |
| | |
| | service_account_json = os.environ.get("FIREBASE_SERVICE_ACCOUNT_JSON") |
| | |
| | if service_account_json: |
| | try: |
| | service_account_info = json.loads(service_account_json) |
| | cred = credentials.Certificate(service_account_info) |
| | firebase_admin.initialize_app(cred) |
| | _firebase_initialized = True |
| | print("[INFO] Firebase Admin SDK initialized from environment variable") |
| | return |
| | except json.JSONDecodeError: |
| | print("[WARNING] Failed to parse FIREBASE_SERVICE_ACCOUNT_JSON") |
| | |
| | |
| | service_account_path = os.environ.get("FIREBASE_SERVICE_ACCOUNT_KEY") |
| | if service_account_path and os.path.exists(service_account_path): |
| | cred = credentials.Certificate(service_account_path) |
| | firebase_admin.initialize_app(cred) |
| | _firebase_initialized = True |
| | print(f"[INFO] Firebase Admin SDK initialized from file: {service_account_path}") |
| | return |
| | |
| | |
| | try: |
| | firebase_admin.initialize_app() |
| | _firebase_initialized = True |
| | print("[INFO] Firebase Admin SDK initialized with default credentials") |
| | return |
| | except Exception as e: |
| | print(f"[WARNING] Firebase initialization failed: {e}") |
| | raise HTTPException( |
| | status_code=500, |
| | detail="Firebase not configured. Please set FIREBASE_SERVICE_ACCOUNT_JSON or FIREBASE_SERVICE_ACCOUNT_KEY environment variable." |
| | ) |
| |
|
| |
|
| | async def verify_firebase_token(id_token: str) -> dict: |
| | """ |
| | Verify Firebase ID token and return user info. |
| | |
| | Args: |
| | id_token: Firebase ID token from client |
| | |
| | Returns: |
| | Dictionary with user information (uid, email, name, picture) |
| | |
| | Raises: |
| | HTTPException: If token is invalid |
| | """ |
| | initialize_firebase() |
| | |
| | try: |
| | decoded_token = auth.verify_id_token(id_token) |
| | |
| | return { |
| | 'uid': decoded_token['uid'], |
| | 'email': decoded_token.get('email'), |
| | 'name': decoded_token.get('name'), |
| | 'picture': decoded_token.get('picture'), |
| | } |
| | except ValueError as e: |
| | raise HTTPException( |
| | status_code=401, |
| | detail=f"Invalid Firebase token: {str(e)}" |
| | ) |
| | except Exception as e: |
| | raise HTTPException( |
| | status_code=401, |
| | detail=f"Firebase authentication failed: {str(e)}" |
| | ) |
| |
|