Firebase Admin Python SDK

repository·main·Indexed 22 days ago

https://github.com/firebase/firebase-admin-python

A SDK for interacting with Firebase services from privileged, server-side environments using Python 3.10+ (3.9 deprecated). It provides comprehensive tools for Firebase Auth, including user management, custom token creation, ID token and session cookie verification, and Identity Platform tenant management. Additionally, it supports Realtime Database operations such as data read/write (set, update, push), atomic transactions, and complex querying and filtering.

Tokens
5.3K
Snippets
16
Records
18
Agent score
76%

What's inside firebase-admin-python

  1. Manage Identity Platform Tenants

    main

    For multi-tenant applications, use the tenant_mgt module to manage tenants and tenant-specific authentication.

    • Tenant Management: Use tenant_mgt.create_tenant(...), tenant_mgt.get_tenant(tenant_id), tenant_mgt.update_tenant(...), and tenant_mgt.list_tenants().
    • Tenant-Specific Auth: To perform auth operations within a specific tenant, obtain a tenant-specific client using tenant_mgt.auth_for_tenant(tenant_id). This client behaves like the standard auth module but is scoped to that tenant.

    Note: When verifying an ID token in a multi-tenant environment, check the firebase.tenant field in the decoded claims to ensure it matches your expected TENANT-ID to avoid TenantIdMismatchError.

    from firebase_admin import tenant_mgt
    
    # Get a client scoped to a specific tenant
    tenant_client = tenant_mgt.auth_for_tenant('TENANT-ID')
    
    # Use the tenant client to manage users within that tenant
    user = tenant_client.get_user('some-uid')
    
    # Verify an ID token and check tenant membership
    try:
        decoded_token = auth.verify_id_token(id_token)
        tenant_id = decoded_token['firebase']['tenant']
        if tenant_id == 'EXPECTED_TENANT_ID':
            # Proceed
            pass
    except tenant_mgt.TenantIdMismatchError:
        # Token belongs to a different tenant
        pass
  2. Initialize Firebase Admin with different privilege levels

    main

    You can control the level of access the Admin SDK has to the Realtime Database by configuring databaseAuthVariableOverride during initialize_app.

    1. Admin Privileges: By default, using a service account grants full read/write access, bypassing Security Rules.
    2. Limited Privileges: Pass a dictionary to databaseAuthVariableOverride (e.g., {'uid': 'my-service-worker'}) to make the SDK act as a specific authenticated user. Access is then restricted by your Security Rules.
    3. Guest Privileges: Set databaseAuthVariableOverride to None to make the SDK act as an unauthenticated guest. Access is restricted to public data defined in Security Rules.
    import firebase_admin
    from firebase_admin import credentials
    
    # 1. Admin Privileges (Full access)
    cred = credentials.Certificate('path/to/serviceAccountKey.json')
    firebase_admin.initialize_app(cred, {
        'databaseURL': 'https://databaseName.firebaseio.com'
    })
    
    # 2. Limited Privileges (Acts as a specific user)
    firebase_admin.initialize_app(cred, {
        'databaseURL': 'https://databaseName.firebaseio.com',
        'databaseAuthVariableOverride': {
            'uid': 'my-service-worker'
        }
    })
    
    # 3. Guest Privileges (Acts as unauthenticated)
    firebase_admin.initialize_app(cred, {
        'databaseURL': 'https://databaseName.firebaseio.com',
        'databaseAuthVariableOverride': None
    })
  3. Initialize the Firebase Admin SDK

    main

    You can initialize the Firebase Admin SDK using several methods depending on your environment and authentication requirements:

    1. Service Account Certificate: Use a JSON file downloaded from the Firebase Console.
    2. Application Default Credentials (ADC): Automatically uses credentials from the environment (e.g., Google Cloud environment).
    3. Refresh Token: Uses a refresh token JSON file.
    4. Service Account ID: Pass specific options like serviceAccountId during initialization.

    To use multiple Firebase apps in one process, provide a unique name argument to initialize_app.

    import firebase_admin
    from firebase_admin import credentials
    
    # Using a service account certificate
    cred = credentials.Certificate('path/to/serviceAccountKey.json')
    def_app = firebase_admin.initialize_app(cred)
    
    # Using Application Default Credentials
    def_app = firebase_admin.initialize_app()
    
    # Initializing a named app (non-default)
    other_app = firebase_admin.initialize_app(cred, name='other')
  4. Write data to Realtime Database

    main

    Use db.reference() to get a reference to a path, then use one of the following methods to write data:

    • set(data): Overwrites the data at the specified path with the new data.
    • update(data): Updates specific children. For nested updates, use paths as keys (e.g., {'users/alanisawesome/nickname': 'New Name'}).
    • push(data): Generates a unique key and adds the data under that key (ideal for lists/logs).
    • child(path): Returns a reference to a child node of the current reference.
    from firebase_admin import db
    
    ref = db.reference('server/saving-data/fireblog')
    
    # Set value (overwrites)
    ref.child('users').set({
        'user1': {'name': 'Alice'}
    })
    
    # Update specific fields
    ref.child('users').update({
        'user1/nickname': 'Alice the Great'
    })
    
    # Push a new item with a unique ID
    posts_ref = ref.child('posts')
    posts_ref.push({
        'author': 'gracehop',
        'title': 'Announcing COBOL'
    })
  5. Verify ID Tokens and Session Cookies

    main

    To authenticate requests from a client, verify the ID token or session cookie sent by the client.

    • Verify ID Token: Use auth.verify_id_token(id_token, check_revoked=False). Setting check_revoked=True ensures the token hasn't been revoked.
    • Verify Session Cookie: Use auth.verify_session_cookie(session_cookie, check_revoked=False). This is useful for long-lived server-side sessions.

    Error Handling:

    • auth.RevokedIdTokenError: The token was revoked.
    • auth.UserDisabledError: The user account is disabled.
    • auth.InvalidIdTokenError: The token is malformed or invalid.
    • auth.InvalidSessionCookieError: The session cookie is invalid, expired, or revoked.
    from firebase_admin import auth
    
    # Verify an ID token
    try:
        decoded_token = auth.verify_id_token(id_token, check_revoked=True)
        uid = decoded_token['uid']
    except auth.RevokedIdTokenError:
        # Handle revoked token
        pass
    except auth.InvalidIdTokenError:
        # Handle invalid token
        pass
    
    # Verify a session cookie
    try:
        decoded_claims = auth.verify_session_cookie(session_cookie, check_revoked=True)
    except auth.InvalidSessionCookieError:
        # Handle invalid/expired cookie
        pass
  6. Perform transactions in Realtime Database

    main

    Use transaction(update_function) to perform atomic updates. The update_function receives the current value and should return the new value. If the transaction fails to commit due to concurrent writes, it raises db.TransactionAbortedError.

    from firebase_admin import db
    
    def increment_votes(current_value):
        return current_value + 1 if current_value else 1
    
    upvotes_ref = db.reference('posts/-JRHTHaIs-jNPLXOQivY/upvotes')
    
    try:
        new_vote_count = upvotes_ref.transaction(increment_votes)
        print('Transaction completed')
    except db.TransactionAbortedError:
        print('Transaction failed to commit')
  7. Manage Users in Firebase Auth

    main

    The auth module provides comprehensive user management capabilities:

    • Create User: auth.create_user(...) allows creating users with email, phone, password, and display name.
    • Get User: auth.get_user(uid) or auth.get_user_by_email(email) or auth.get_user_by_phone_number(phone).
    • Update User: auth.update_user(uid, ...) to modify user properties.
    • Delete User: auth.delete_user(uid) or auth.delete_users([uids]) for bulk deletion.
    • List Users: auth.list_users() returns a paginated list. Use .iterate_all() to iterate through all users automatically.
    • Bulk Operations: auth.get_users([identifiers]) allows fetching multiple users by UidIdentifier, EmailIdentifier, PhoneIdentifier, or ProviderIdentifier in one call.
    from firebase_admin import auth
    
    # Create a user
    user = auth.create_user(email='user@example.com', display_name='John Doe')
    
    # Get a user by UID
    user = auth.get_user('some-uid')
    
    # Bulk fetch users by different identifiers
    result = auth.get_users([
        auth.UidIdentifier('uid1'),
        auth.EmailIdentifier('user2@example.com'),
        auth.PhoneIdentifier('+15555550003'),
        auth.ProviderIdentifier('google.com', 'google_uid4')
    ])
    
    # Iterate through all users
    for user in auth.list_users().iterate_all():
        print(user.uid)
  8. Manage custom user claims for a tenant

    main

    Custom claims allow you to add administrative privileges or other metadata to a user's ID token.

    • Set claims: Use tenant_client.set_custom_user_claims(uid, claims_dict) to assign claims. These propagate to the user's ID token upon the next issuance.
    • Verify claims: After verifying an ID token with tenant_client.verify_id_token(id_token), access the claims via the returned dictionary.
    • Read claims: Retrieve a user record using tenant_client.get_user(uid) and access claims via the custom_claims attribute.
    # Set custom claims
    tenant_client.set_custom_user_claims(uid, {'admin': True})
    
    # Verify claims from an ID token
    claims = tenant_client.verify_id_token(id_token)
    if claims['admin'] is True:
        # Allow access
        pass
    
    # Read claims from a user record
    user = tenant_client.get_user(uid)
    print(user.custom_claims.get('admin'))
  9. Generate an email verification link for a tenant

    main

    To generate a link for email verification, use tenant_client.generate_email_verification_link(email, action_code_settings).

    Configuration is handled via auth.ActionCodeSettings, which allows you to specify:

    • url: The URL to redirect to after the link is clicked.
    • handle_code_in_app: Boolean indicating if the app should handle the code.
    • ios_bundle_id / android_package_name: Platform-specific identifiers.
    • android_install_app: Boolean to trigger app installation.
    • dynamic_link_domain: The FDL custom domain.
    from firebase_admin import auth
    
    action_code_settings = auth.ActionCodeSettings(
        url='https://www.example.com/checkout?cartId=1234',
        handle_code_in_app=True,
        ios_bundle_id='com.example.ios',
        android_package_name='com.example.android',
        android_install_app=True,
        android_minimum_version='12',
        dynamic_link_domain='coolapp.page.link',
    )
    
    email = 'user@example.com'
    link = tenant_client.generate_email_verification_link(email, action_code_settings)