Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Concurrently creating firebase users of the same email succeeds

Đang mở
#809 1 bình luận 4 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
30/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
python
Lĩnh vực
authentication

Hướng nghiên cứu

Cách tái hiện được nêu trong firebase_service.py và test.py; trước tiên hãy chạy trường hợp ThreadPoolExecutor với Firebase Authentication và so sánh với trường hợp asyncio. Điều tra đường dẫn SDK được auth.create_user sử dụng và xác định xem các yêu cầu đồng thời có được xử lý nhất quán hay không. Công việc được xem là hoàn tất khi trường hợp đồng thời không còn tạo nhiều người dùng có cùng email và hành vi EmailAlreadyExistsError mong đợi đã được xác minh.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

api: auth
[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 the firebase tag.
  • 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:

  1. Create the new user (with existing email) a second after the existing user was created
    1.1. I get the firebase_admin._auth_utils.EmailAlreadyExistsError like I expect

  2. 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 3 firebase_admin._auth_utils.EmailAlreadyExistsError like 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())

Ngôn ngữ chính
Python
Star
1.2k
Fork
359
Merge trung bình
5 ngày 6 phút
Pull request đã merge (30 ngày)
2

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của firebase/firebase-admin-python

Tất cả issue của firebase/firebase-admin-python

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.