-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Describe the bug
The Firebase Functions Emulator, when running Python code using the V1 Cloud Event handler (functions-framework), fails to trigger the create_user_profile function upon user creation in the Authentication Emulator. This occurs despite the emulators starting successfully and loading the function definition without Python import errors. The issue persists even when creating the user programmatically via the Admin SDK targeting the Auth emulator. The problem appears to be a failure in the event delivery mechanism between the Auth and Functions emulators for this specific trigger type in the Cloud Shell environment.
To Reproduce
Steps to reproduce the behavior in Google Cloud Shell:
Start with a clean Cloud Shell environment.
Install latest firebase-tools (npm i -g firebase-tools@latest).
Log in (firebase login --no-localhost).
Create project files (firebase init):
Select Firestore, Functions, Emulators.
Use an existing project.
Configure Firestore (e.g., (default), rules, indexes).
Configure Functions: Language Python, Overwrite Yes, Install dependencies No.
Configure Emulators: Select Auth, Functions, Firestore. Use default ports (or adjusted non-conflicting ports like Auth: 9100, Functions: 5002, Firestore: 8082, UI: 4001). Download emulators.
Edit firebase.json to set "runtime": "python312" (matching Cloud Shell's default Python 3). Adjust emulator ports if needed.
cd functions
Create venv: python3 -m venv venv
Activate venv: source venv/bin/activate
Create requirements.txt with content:
Plaintext
firebase-admin>=7.1.0
firebase-functions>=0.2.0
functions-framework>=3.0.0
cloudevents>=1.9.0
Install dependencies: pip install -r requirements.txt
Create/Edit main.py with the V1 Cloud Event handler code (see below).
cd ..
Start emulators: firebase emulators:start --only auth,functions,firestore (Emulators start, function definition loads successfully).
Open Emulator UI via Web Preview (e.g., port 4001).
Go to Auth tab -> Click "Add User". Issue: "Save" button is unresponsive (UI bug).
Alternative Trigger: Open a second Cloud Shell terminal, cd wowmotive, source functions/venv/bin/activate, export FIREBASE_AUTH_EMULATOR_HOST="127.0.0.1:[AUTH_PORT]", export GOOGLE_CLOUD_PROJECT="[YOUR_PROJECT_ID]". Create trigger_auth_event.py (see below) and run python trigger_auth_event.py. Issue: User is created successfully in Auth emulator (verified via UI), but no logs appear from the create_user_profile function in the first terminal.
Expected behavior
When a user is created (either via UI or Admin SDK targeting the emulator), the create_user_profile function should execute, and its log messages (V1 HANDLER TRIGGERED...) should appear in the emulator terminal output. A corresponding document should be created in the Firestore emulator.
Actual behavior
The emulators start and load the function definition successfully. However, when a user is created in the Auth emulator (verified via Admin SDK script and UI), the create_user_profile function is never triggered. No logs from the function appear in the terminal, and no document is created in Firestore. The Auth Emulator UI's "Save" button is also unresponsive.
main.py (V1 Cloud Event Handler Code)
Python
functions/main.py (V1 Cloud Event Handler)
import functions_framework
from cloudevents.http import CloudEvent
import firebase_admin
from firebase_admin import firestore, initialize_app
try:
if not firebase_admin._apps:
initialize_app()
except ValueError:
pass
@functions_framework.cloud_event
def create_user_profile(cloud_event: CloudEvent) -> None:
payload = cloud_event.data
if not payload:
print("Error: No data payload in Auth event.")
return
user_uid = payload.get('uid')
user_email = payload.get('email')
metadata = payload.get('metadata', {})
created_at = metadata.get('createdAt')
display_name = payload.get('displayName')
if not user_uid:
print("Error: User UID missing.")
return
print(f"V1 HANDLER TRIGGERED: Processing user: {user_uid}")
db = firestore.client()
user_ref = db.collection('users').document(user_uid)
user_ref.set({
'email': user_email, 'displayName': display_name,
'role': 'driver', 'companyId': None,
'createdAt': created_at if created_at else firestore.SERVER_TIMESTAMP,
'function_gen': 'V1_CloudEvent'
})
print(f"V1 HANDLER SUCCESS: Created Firestore profile for {user_uid}")
trigger_auth_event.py (Used for Testing)
Python
trigger_auth_event.py
import os
import firebase_admin
from firebase_admin import initialize_app, auth
import uuid
auth_emulator_host = os.getenv("FIREBASE_AUTH_EMULATOR_HOST")
if not auth_emulator_host:
print("ERROR: FIREBASE_AUTH_EMULATOR_HOST is not set.")
exit(1)
else:
print(f"Connecting to Auth Emulator at: {auth_emulator_host}")
try:
if not firebase_admin._apps:
initialize_app()
except ValueError:
pass
test_email = f"test_{uuid.uuid4()}@wowmotive.com"
try:
user = auth.create_user(
email=test_email,
password='Password123!',
display_name='Test WowMotive User',
)
print(f"Admin SDK: Successfully created new user. UID: {user.uid}")
print("Check Functions Emulator logs.")
except Exception as e:
print(f"Admin SDK User creation failed: {e}")
requirements.txt
Plaintext
firebase-admin>=7.1.0
firebase-functions>=0.2.0
functions-framework>=3.0.0
cloudevents>=1.9.0
firebase.json (relevant parts)
JSON
{
"functions": [
{
"source": "functions",
"codebase": "default",
"ignore": ["venv", ".git", "firebase-debug.log", "firebase-debug..log", ".local"],
"runtime": "python312"
}
],
"emulators": {
"auth": { "port": 9100 },
"functions": { "port": 5002 },
"firestore": { "port": 8082 },
"ui": { "enabled": true, "port": 4001 }, // Port might vary
"singleProjectMode": true
}
}
Platform: Google Cloud Shell Tool Versions:
firebase-tools: [PASTE LATEST VERSION USED, e.g., 14.20.0]
Platform: Linux (Cloud Shell)
Node: [PASTE node --version OUTPUT]
Python: [PASTE python3 --version OUTPUT, e.g., 3.12.3]
Other information:
Attach the firebase-debug.log generated by running firebase emulators:start --only auth,functions,firestore --debug during a failed run (where the trigger doesn't fire).