Guia de migração do SDK Admin para Python 3.0.0

A versão 3.0.0 do SDK Admin do Firebase para Python introduz algumas alterações importantes na API. Em primeiro lugar, as alterações da API nesta versão são adições e melhorias no tratamento de erros para Auth, FCM e outros recursos do Firebase.

Alterações gerais no tratamento de erros

Os seguintes tipos de exceção foram removidos:

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

Em vez disso, um novo módulo firebase_admin.exceptions foi introduzido. As APIs públicas nos módulos auth, db, instance_id, messaging e project_management agora geram instâncias do 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

O tipo exceptions.FirebaseError tem muitos subtipos. As APIs públicas no SDK Admin só podem gerar esses subtipos. Portanto, você pode escrever um código que identifique um subtipo específico e processe erros de forma mais granular. Exemplo:

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

Em vez de capturar tipos de erro específicos, também é possível capturar o tipo FirebaseError pai e comparar os códigos de erro.

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 pode declarar outros subtipos que se estendam do tipo pai exceptions.FirebaseError (veja abaixo).

Diretrizes gerais para tratamento de erros: detecte exceptions.FirebaseError quando não precisar diferenciar as condições de erro. Procure uma subclasse de erro mais específica ou um código de erro quando precisar diferenciar condições de erro.

Alterações no tratamento de erros de autenticação

Verificação de JWT

O método auth.verify_id_token() não gera mais ValueError para indicar erros de validação de token. Em vez disso, você receberá um dos seguintes tipos de erro:

  • InvalidIdTokenError
  • ExpiredIdTokenError
  • RevokedIdTokenError

O tipo InvalidIdTokenError estende o tipo exceptions.InvalidArgumentError, que, por sua vez, estende o tipo exceptions.FirebaseError. ExpiredIdTokenError e RevokedIdTokenError estendem 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')

Da mesma maneira, o método auth.verify_session_cookie() gera os seguintes tipos de exceção:

  • InvalidSessionCookieError
  • ExpiredSessionCookieError
  • RevokedSessionCookieError

A hierarquia e a semântica de classes são semelhantes à API verify_id_token().

Tokens personalizados

A API create_custom_token() gera auth.TokenSignError em vez de ValueError para indicar falhas.

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

Gerenciamento de usuários

Os novos tipos de erro a seguir foram introduzidos no 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')

Alterações no tratamento de erros do FCM

Os novos tipos de erro a seguir foram introduzidos no 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')

Exclusão da propriedade do usuário

Não é mais possível excluir as propriedades display_name, photo_url, phone_number e custom_claims definindo-as como None. A definição delas como None não altera essas propriedades. Elas precisam ser definidas explicitamente como auth.DELETE_ATTRIBUTE para excluí-las.

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