Concurrently creating firebase users of the same email succeeds
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 30/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 停滞
- 技术栈
- python
调研方向
复现过程在 firebase_service.py 和 test.py 中有说明;首先针对 Firebase Authentication 运行 ThreadPoolExecutor 案例,并将其与 asyncio 案例进行比较。调查 auth.create_user 使用的 SDK 路径,并确定并发请求是否得到一致处理。完成的标准是并发案例不再创建具有相同电子邮件地址的多个用户,并验证预期的 EmailAlreadyExistsError 行为。
由索引模型根据 Issue 内容生成。
描述
[READ] Step 1: Are you in the right place?
- For issues related to the code in this repository file a GitHub issue.
- If the issue pertains to Cloud Firestore, report directly in the
Python Firestore GitHub repo. Firestore
bugs reported in this repo will be closed with a reference to the Python Firestore
project. - For general technical questions, post a question on StackOverflow
with thefirebasetag. - For general Firebase discussion, use the firebase-talk
google group. - For help troubleshooting your application that does not fall under one
of the above categories, reach out to the personalized
Firebase support channel.
[REQUIRED] Step 2: Describe your environment
- Operating System version: MacOS sonoma 14.3
- Firebase SDK version: 6.5.0
- Firebase Product: auth
- Python version: 3.11
- Pip version: 23.1.2
Note that I have used other tenants on Google Identity Platform in this gcp project but I scrapped that and went back to the single tenant.
This issue is happening on the default firebase tenant. (Sharing this fact in case it somehow affects the outcome)
[REQUIRED] Step 3: Describe the problem
I discovered that my tests for some CRUD functionality were creating duplicate firebase users with the same email which is problematic because we rely on the firebase_admin._auth_utils.EmailAlreadyExistsError to safeguard functionality. This appeared as my webserver API was called to create the same user concurrently and it actually made multiple firebase users.
For context, my firebase project -> authentication -> settings -> user account linking -> link accounts with same email is active.
Steps to reproduce:
Creating a new user with an existing email address succeeds when its ran concurrently. I have tested 3 scenarios:
-
Create the new user (with existing email) a second after the existing user was created
1.1. I get thefirebase_admin._auth_utils.EmailAlreadyExistsErrorlike I expect -
Attempt to create 4 users with the same email address using asyncio library to create them quickly
2.1 Returns one created user and fires 3firebase_admin._auth_utils.EmailAlreadyExistsErrorlike I expect
3. Attempt to create 4 users with the same email address concurrently using ThreadPoolExecutor
3.1 Returns 4 new Firebase users who all share the same email address. Not good.
Calling the auth.get_user_by_email(email) returns the latest firebase user created, when I delete the latest one then the function returns the newest one after that and so on.
I plan to add in concurrency/idempotent protections to my API logic in the mean time as this would cause a mess downstream ( as uncommon as it would occur)
Relevant Code:
This is a rough outline of my tests but in general just call create_user concurrently to hopefully see the same results. I use a Fastapi server so you can ignore some of this extracted code using async where its not needed. This is just to demo the issue.
firebase_service.py
import firebase_admin
from firebase_admin import auth
if not firebase_admin._apps:
firebase_admin.initialize_app()
class FirebaseService:
# async wrapper
async def create_user(self, email: str, uid: str | None) -> auth.UserRecord | None:
"""Create a user."""
try:
user = auth.create_user(email=email, uid=uid)
return user
except Exception as e:
logger.exception(f"error creating user {email} : {e}")
return None
# non async implementation
def create_user_sync(self, email: str, uid: str | None) -> auth.UserRecord | None:
"""Create a user."""
try:
user = auth.create_user(email=email, uid=uid)
return user
except Exception as e:
logger.exception(f"error creating user {email} : {e}")
return None
test.py
import asyncio
common_email = "email_goes_here"
no_uid = None
async def test_multiple_user_same_email_create_asyncio() -> None:
"""Test multiple user creation with same email with asyncio gather."""
tasks = []
for i in range(4):
tasks.append(asyncio.create_task(firebase_service.create_user(uid=no_uid, email=common_email)))
results = await asyncio.gather(*tasks)
logger.info(results) # correctly creates 1 user and raises an error for the rest
async def test_multiple_user_same_email_create_threadpool() -> None:
"""Test multiple user creation with same email concurrently"""
uid = None
with ThreadPoolExecutor(max_workers=4) as executor:
futures = [executor.submit(firebase_service.create_user_sync,common_email, no_uid ) for _ in range(4)]
results = [future.result() for future in as_completed(futures)]
logger.info(results) # actually creates 4 users with the same email
if __name__ == "__main__":
# asyncio.run(test_multiple_user_same_email_create_asyncio())
# asyncio.run(test_multiple_user_same_email_create_threadpool())
- 主要语言
- Python
- 星标
- 1.2k
- 派生
- 359
- 平均合并
- 5 天 6 分钟
- 30 天内合并 PR
- 2
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
firebase/firebase-admin-python 的其他 Issue
-
api: remoteconfig
难度 2/5 1-3 小时 新手友好度 75/100
firebase/firebase-admin-python#957 · 1 条评论 ·
-
api: database type: feature request
难度 2/5 1-3 小时 新手友好度 62/100
-
难度 4/5 3-5 天 新手友好度 45/100
firebase/firebase-admin-python#978 · 1 条评论 ·
-
[FR] Support VERIFY_AND_CHANGE_EMAIL in generate_email_action_link (parity with firebase-admin-node) 未关闭api: auth
firebase/firebase-admin-python#949 · 2 条评论 · 1 个 reaction · 已指派 1 人 ·
-
难度 4/5 3-5 天 新手友好度 43/100
firebase/firebase-admin-python#945 · 1 条评论 · 1 个 reaction ·
查看 firebase/firebase-admin-python 的全部 Issue
相似的 Issue
-
Add: hunch 未关闭
难度 2/5 1-3 小时 新手友好度 74/100
AbdelStark/awesome-typesafe#104 ·
-
enhancement
难度 2/5 1-3 小时 新手友好度 72/100
-
难度 2/5 1-3 小时 新手友好度 68/100
DiamondLightSource/dodal#2211 ·
-
难度 2/5 1-3 小时 新手友好度 88/100
openml/openml-python#1749 ·
-
难度 2/5 1-3 小时 新手友好度 88/100
sipyourdrink-ltd/bernstein#6191 ·