В версии 3.0.0 Firebase Admin SDK для Python внесены некоторые важные изменения в API. Прежде всего, изменения API в этом выпуске — это дополнения и улучшения в обработке ошибок для Auth, FCM и других функций Firebase.
Общие изменения обработки ошибок
Были удалены следующие типы исключений:
-
auth.AuthError
-
db.ApiCallError
-
instance_id.ApiCallError
-
messaging.ApiCallError
-
project_management.ApiCallError
Вместо этого был представлен новый модуль firebase_admin.exceptions
. Публичные API в модулях auth
, db
, instance_id
, messaging
и project_management
теперь вызывают экземпляры типа 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
У типа exceptions.FirebaseError
есть много подтипов. Общедоступные API в Admin SDK могут создавать только эти подтипы. Таким образом, вы можете написать код, который улавливает определенный подтип и более детально обрабатывает ошибки. Например:
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
Вместо перехвата определенных типов ошибок также можно перехватывать родительский тип FirebaseError
и сравнивать коды ошибок.
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
Каждый модуль может объявлять дополнительные подтипы, расширяющиеся от родительского типа exceptions.FirebaseError
(см. ниже).
Общее руководство по обработке ошибок: Перехватывайте exceptions.FirebaseError
, когда вам не нужно различать состояния ошибок. Ищите более конкретный подкласс ошибки или код ошибки, когда вам нужно дифференцировать условия ошибки.
Изменения в обработке ошибок аутентификации
JWT-проверка
Метод auth.verify_id_token()
больше не вызывает ValueError
, чтобы указать на ошибки проверки токена. Вместо этого вы получите один из следующих типов ошибок:
-
InvalidIdTokenError
-
ExpiredIdTokenError
-
RevokedIdTokenError
Тип InvalidIdTokenError
расширяет тип exceptions.InvalidArgumentError
, который, в свою очередь, расширяет тип exceptions.FirebaseError
. ExpiredIdTokenError
и RevokedIdTokenError
расширяют 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')
Точно так же метод auth.verify_session_cookie()
вызывает следующие типы исключений:
-
InvalidSessionCookieError
-
ExpiredSessionCookieError
-
RevokedSessionCookieError
Иерархия и семантика классов аналогичны API verify_id_token()
.
Пользовательские токены
API create_custom_token()
вызывает auth.TokenSignError
вместо ValueError
, чтобы указать на ошибки.
# 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)
Управление пользователями
В модуль 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')
Изменения обработки ошибок FCM
В модуль 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')
Удаление свойства пользователя
Больше невозможно удалить свойства display_name
, photo_url
, phone_number
и custom_claims
, установив для них значение None
. Установка для них None
оставляет эти свойства без изменений. Для их удаления необходимо явно установить значение 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)