Vai alla console

Admim SDK for Python 3.0.0 migration guide

Version 3.0.0 of the Firebase Admin SDK for Python introduces some important changes in the API. Primarily, the API changes in this release are additions and improvements in error handling for Auth, FCM, and other Firebase features.

General error handling changes

The following exception types have been removed:

  • auth.AuthError
  • db.ApiCallError
  • instance_id.ApiCallError
  • messaging.ApiCallError
  • project_management.ApiCallError

Instead, a new firebase_admin.exceptions module has been introduced. Public APIs in auth, db, instance_id, messaging and project_management modules now raise instances of exceptions.FirebaseError type.

# Before
from firebase_admin import messaging

try:
    messaging.send(build_message())
except messaging.ApiCallError as ex:
    print('Error message:', ex)

# v3
from firebase_admin import exceptions
from firebase_admin import messaging

try:
    messaging.send(build_message())
except exceptions.FirebaseError as ex:
    print('Error message:', ex)
    print('Error code:', ex.code) # Platform-wide error code
    print('HTTP response:', ex.http_response) # requests HTTP response object

The exceptions.FirebaseError type has many subtypes. Public APIs in the Admin SDK can only raise these subtypes. Therefore, you can write code that catches a specific subtype and handles errors more granularly. For example:

try:
    messaging.send(build_message())
except exceptions.InvalidArgumentError as ex:
    print(ex) # One or more arguments were invalid
except exceptions.UnavailableError as ex:
    print(ex) # FCM service is temporarily down
except exceptions.FirebaseError as ex:
    print(ex) # All other errors

Instead of catching specific error types, it is also possible to catch the parent FirebaseError type and compare error codes.

try:
    messaging.send(build_message())
except exceptions.FirebaseError as ex:
    if ex.code == exceptions.INVALID_ARGUMENT:
        print(ex) # One or more arguments were invalid
    elif ex.code == exceptions.UNAVAILABLE:
        print(ex) # FCM service is temporarily down
    else:
        print(ex) # All other errors

Each module may declare additional subtypes extending from the exceptions.FirebaseError parent type (see below).

General guideline for error handling: Catch exceptions.FirebaseError when you don’t need to differentiate between error conditions. Look for a more specific error subclass or error code when you need to differentiate error conditions.

Auth error handling changes

JWT Verification

The auth.verify_id_token() method no longer raises ValueError to indicate token validation errors. Instead, you will get one of the following error types:

  • InvalidIdTokenError
  • ExpiredIdTokenError
  • RevokedIdTokenError

The InvalidIdTokenError type extends the exceptions.InvalidArgumentError type, which in turns extends the exceptions.FirebaseError type. ExpiredIdTokenError and RevokedIdTokenError extend InvalidIdTokenError.

# Before
from firebase_admin import auth

try:
    auth.verify_id_token(id_token, check_revoked=True)
except ValueError as ex:
    print('Error message:', ex)

 # v3
from firebase_admin import auth

# Coarse-grained error handling
try:
    auth.verify_id_token(id_token, check_revoked=True)
except auth.InvalidIdTokenError as ex:
    print('ID token is invalid, expired or revoked')

# Fine-grained error handling
try:
    auth.verify_id_token(id_token, check_revoked=True)
except auth.RevokedIdTokenError as ex:
    print('ID token has been revoked')
except auth.ExpiredIdTokenError as ex:
    print('ID token is expired')
except auth.InvalidIdTokenError as ex:
    print('ID token is invalid')

Similarly, the auth.verify_session_cookie() method raises the following exception types:

  • InvalidSessionCookieError
  • ExpiredSessionCookieError
  • RevokedSessionCookieError

Class hierarchy and semantics are similar to the verify_id_token() API.

Custom tokens

The create_custom_token() API raises auth.TokenSignError instead of ValueError to indicate failures.

# Before
from firebase_admin import auth

try:
    auth.create_custom_token(uid)
except ValueError as ex:
    print('Error message:', ex)

 # v3
from firebase_admin import auth

try:
    auth.create_custom_token(uid)
except auth.TokenSignError as ex:
    print('Error message:', ex)

User management

The following new error types have been introduced to the auth module:

  • EmailAlreadyExistsError
  • InvalidDynamicLinkDomainError
  • PhoneNumberAlreadyExistsError
  • UidAlreadyExistsError
  • UnexpectedResponseError
  • UserNotFoundError
# Before
from firebase_admin import auth

try:
    auth.get_user(uid)
except auth.AuthError as ex:
    if ex.code == auth.USER_NOT_FOUND_ERROR:
        print('Specified user does not exist')
    else:
        print('Something else went wrong')

 # v3
from firebase_admin import auth
from firebase_admin import exceptions

try:
    auth.get_user(uid)
except auth.UserNotFoundError as ex:
    print('Specified user does not exist')
except exceptions.FirebaseError as ex:
    print('Something else went wrong')

FCM Error handling changes

The following new error types have been introduced to the messaging module.

  • QuotaExceededError
  • SenderIdMismatchError
  • ThirdPartyAuthError
  • UnregisteredError
# Before
from firebase_admin import messaging

try:
    messaging.send(msg)
except messaging.ApiCallError as ex:
    if ex.code == 'registration-token-not-registered':
        print('Registration token has been unregistered')
    elif ex.code == 'invalid-argument':
        print('One or more arguments invalid')
    else:
        print('Something else went wrong')

# v3
from firebase_admin import exceptions
from firebase_admin import messaging

try:
    messaging.send(msg)
except messaging.UnregisteredError as ex:
    print('Registration token has been unregistered')
except exceptions.InvalidArgumentError as ex:
    print('One or more arguments invalid')
except exceptions.FirebaseError as ex:
    print('Something else went wrong')

User property deletion

It is no longer possible to delete properties display_name, photo_url, phone_number and custom_claims by setting them to None. Setting these to None leaves these properties unchanged. They must be explicitly set to auth.DELETE_ATTRIBUTE to delete them.

# Before
from firebase_admin import auth

auth.update_user(uid, display_name=None, photo_url=None)

 # v3
from firebase_admin import auth

auth.update_user(
  uid, display_name=auth.DELETE_ATTRIBUTE, photo_url=auth.DELETE_ATTRIBUTE)