python - 使用 firebase_admin 或 google.cloud.firestore 在 python 中的 Firestore 客户端(作为用户)

标签 python google-cloud-firestore firebase-authentication google-authentication firebase-admin

我正在构建一个使用 Firestore 的 python 客户端应用程序。我已成功使用 Google Identity Platform 注册并登录 Firebase 项目,并使用 google.cloud.firestore.Client 创建了一个有效的 Firestore 客户端,该客户端已通过用户身份验证:

import json
import requests
import google.oauth2.credentials
from google.cloud import firestore

request_url = f"https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={self.__api_key}"
headers = {"Content-Type": "application/json; charset=UTF-8"}
data = json.dumps({"email": self.__email, "password": self.__password, "returnSecureToken": True})
response = requests.post(request_url, headers=headers, data=data)
try:
    response.raise_for_status()
except (HTTPError, Exception):
    content = response.json()
    error = f"error: {content['error']['message']}"
    raise AuthError(error)

json_response = response.json()
self.__token = json_response["idToken"]
self.__refresh_token = json_response["refreshToken"]

credentials = google.oauth2.credentials.Credentials(self.__token,
                                                    self.__refresh_token,
                                                    client_id="",
                                                    client_secret="",
                                                    token_uri=f"https://securetoken.googleapis.com/v1/token?key={self.__api_key}"
                                                    )

self.__db = firestore.Client(self.__project_id, credentials)
但是,我有一个问题,当 token 过期时,我收到以下错误:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/dist-packages/google/api_core/grpc_helpers.py", line 57, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/grpc/_channel.py", line 826, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "/usr/local/lib/python3.7/dist-packages/grpc/_channel.py", line 729, in _end_unary_response_blocking
    raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
    status = StatusCode.UNAUTHENTICATED
    details = "Missing or invalid authentication."
    debug_error_string = "{"created":"@1613043524.699081937","description":"Error received from peer ipv4:172.217.16.74:443","file":"src/core/lib/surface/call.cc","file_line":1055,"grpc_message":"Missing or invalid authentication.","grpc_status":16}"
>

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/home/my_app/src/controllers/im_alive.py", line 20, in run
    self.__device_api.set_last_updated(utils.device_id())
  File "/home/my_app/src/api/firestore/firestore_device_api.py", line 21, in set_last_updated
    "lastUpdatedTime": self.__firestore.SERVER_TIMESTAMP
  File "/home/my_app/src/api/firestore/firestore.py", line 100, in update
    ref.update(data)
  File "/usr/local/lib/python3.7/dist-packages/google/cloud/firestore_v1/document.py", line 382, in update
    write_results = batch.commit()
  File "/usr/local/lib/python3.7/dist-packages/google/cloud/firestore_v1/batch.py", line 147, in commit
    metadata=self._client._rpc_metadata,
  File "/usr/local/lib/python3.7/dist-packages/google/cloud/firestore_v1/gapic/firestore_client.py", line 1121, in commit
    request, retry=retry, timeout=timeout, metadata=metadata
  File "/usr/local/lib/python3.7/dist-packages/google/api_core/gapic_v1/method.py", line 145, in __call__
    return wrapped_func(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/google/api_core/retry.py", line 286, in retry_wrapped_func
    on_error=on_error,
  File "/usr/local/lib/python3.7/dist-packages/google/api_core/retry.py", line 184, in retry_target
    return target()
  File "/usr/local/lib/python3.7/dist-packages/google/api_core/timeout.py", line 214, in func_with_timeout
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/google/api_core/grpc_helpers.py", line 59, in error_remapped_callable
    six.raise_from(exceptions.from_grpc_error(exc), exc)
  File "<string>", line 3, in raise_from
google.api_core.exceptions.Unauthenticated: 401 Missing or invalid authentication.
我尝试省略 token 并仅指定刷新 token ,然后调用 credentials.refresh() ,但 expires_inhttps://securetoken.googleapis.com/v1/token 的回复中端点是一个字符串而不是一个数字( docs here ),这使得 _parse_expiry(response_data)google.oauth2._client.py:257引发异常。
有什么方法可以使用firestore.Client来自google.cloudfirebase_admin并让它自动处理刷新 token ,还是我需要切换到手动调用 Firestore RPC API 并在正确的时间刷新 token ?
注意:没有用户与 python 应用程序交互,因此解决方案必须不需要用户交互。

最佳答案

您不能将字符串转换为整数 _parse_expiry(int(float(response_data))) ?
如果它不起作用,您可以在获取错误 401 后尝试调用电话并刷新 token ,请参阅我的 answer有关如何处理 token 的一般想法。

关于python - 使用 firebase_admin 或 google.cloud.firestore 在 python 中的 Firestore 客户端(作为用户),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66153262/

相关文章:

python - 如何创建包含空 csv 字段为 None 的字典?

python - 由于 ' 字符,SQLite3 请求不起作用

python - 无法将字节连接到 str

javascript - 如何使用 Firebase Firestore 获取子集合?

javascript - 如何使用 firebase Auth 检索和处理重定向错误?

javascript - Firebase 电话身份验证和链接

python - 在 PyTables 中,如何创建可变长度的嵌套数组?

typescript - Firebase HTTPS 函数 - 在完成后台工作之前响应 200 状态代码

android - 如何在 Android 上使用 whereArrayContains() 过滤器查询包含 Firestore 集合中对象数组的文档?

android - 基于播放服务测量的多个版本请求