Guía de migración del SDK de Admin para Python 3.0.0

La versión 3.0.0 del SDK de Firebase Admin para Python incluye algunos cambios importantes en la API. Primero, los cambios en la API de esta versión son adiciones y mejoras en el manejo de errores de Auth, FCM y otras funciones de Firebase.

Cambios en el manejo general de errores

Se quitaron los siguientes tipos de excepciones:

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

En su lugar, se agregó un nuevo módulo firebase_admin.exceptions. Las API públicas en los módulos auth, db, instance_id, messaging y project_management ahora generan instancias de tipo exceptions.FirebaseError.

# 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

El tipo exceptions.FirebaseError tiene muchos subtipos. Las API públicas del SDK de Admin solo pueden generar estos subtipos. Por lo tanto, puedes escribir código que capte un subtipo específico y controle los errores de forma más detallada. Por ejemplo:

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

En lugar de detectar tipos de errores específicos, también es posible buscar el tipo FirebaseError principal y comparar los códigos de error.

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

Cada módulo puede declarar subtipos adicionales que se extienden desde el tipo superior exceptions.FirebaseError (consulta a continuación).

Lineamientos generales para el manejo de errores: Detecta exceptions.FirebaseError cuando no necesites diferenciar entre las condiciones de error. Busca una subclase de error o código de error más específico cuando necesites diferenciar las condiciones de error.

Cambios en el manejo de errores de Auth

Verificación de JWT

El método auth.verify_id_token() ya no genera ValueError para indicar errores de validación de los tokens. En su lugar, obtendrás uno de los siguientes tipos de error:

  • InvalidIdTokenError
  • ExpiredIdTokenError
  • RevokedIdTokenError

El tipo InvalidIdTokenError extiende el tipo exceptions.InvalidArgumentError, que a su vez extiende el tipo exceptions.FirebaseError. ExpiredIdTokenError y RevokedIdTokenError extienden 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')

Del mismo modo, el método auth.verify_session_cookie() genera los siguientes tipos de excepción:

  • InvalidSessionCookieError
  • ExpiredSessionCookieError
  • RevokedSessionCookieError

La jerarquía de la clase y la semántica son similares a la API de verify_id_token().

Tokens personalizados

La API de create_custom_token() genera auth.TokenSignError en lugar de ValueError para indicar fallas.

# 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)

Administración de usuarios

Se introdujeron los siguientes tipos de errores nuevos en el módulo auth:

  • 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')

Cambios en el manejo de errores de FCM

Se introdujeron los siguientes tipos de errores nuevos en el módulo messaging.

  • 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')

Eliminación de propiedades del usuario

Ya no se pueden borrar las propiedades display_name, photo_url, phone_number y custom_claims si se configuran como None. Si se configuran como None, estas propiedades no se modifican. Para borrarlas, deben configurarse de forma explícita como auth.DELETE_ATTRIBUTE.

# 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)