Open
Description
I am currently testing the 2nd gen on-write Firestore cloud triggers. For some reason, the trigger freezes and stops executing after a few hours from deployment.
It appears that updating a Firestore document is causing the trigger to freeze.
Environment details
- OS type and version: MacOS Sonoma 14.3.
- Python version: 3.12.2
- pip version: 24.0
google-cloud-firestore
version: 2.15.0
Steps to reproduce
Note that this bug is difficult to reproduce and would require some repetition to occur.
- Deploy the
test_document_write
HTTP request function andtest_on_document_write
on-write Firestore trigger. - Run the
test_document_write
function.
This will create a
test
Firestore collection and will create or update 10 fixed Firestore documents that will trigger thetest_on_document_write
cloud trigger.
- Observe that the
test_on_document_write
will make the changes in the updated Firestore docs. - Wait a couple of hours.
- Re-run the
test_document_write
function. - Observe that the Firestore docs will not update due to the function freezing (as shown in the image above). If it did, repeat step 4.
Code example
test_document_write
HTTP Request Function
- This function creates 10 documents in the
test
collection, and increments their fielda
value.
from app.https.common.http_responses import success_response
from firebase_admin import firestore
from firebase_functions import https_fn, options
from google.cloud.firestore import Client, Increment
@https_fn.on_request(cors=options.CorsOptions(cors_methods=['post']))
def test_document_write(request: https_fn.Request) -> https_fn.Response:
firestore_client: Client = firestore.client()
batch = firestore_client.batch()
for i in range(0, 10):
batch.set(
firestore_client.document(f'test/doc_{i}'),
{'a': Increment(1)},
merge=True,
)
batch.commit()
return success_response()
test_on_document_write
on-write Firestore trigger
- This trigger ensures that field
b
always matches the value of fielda
.
from firebase_functions import logger
from firebase_functions.firestore_fn import (Change, DocumentSnapshot, Event,
on_document_written)
@on_document_written(document='test/{id}')
def test_on_document_write(event: Event[Change[DocumentSnapshot]]):
after = event.data.after
if not after:
return
after_data = event.data.after.to_dict()
a = after_data.get('a', 0)
b = after_data.get('b', 0)
if a != b:
updated_data = {'a': a, 'b': a}
logger.info(
'Updating document: {}, Old data:{}, New data: {}'.format(
event.document,
after_data,
updated_data,
),
)
# Occasionally, it appears that the code is freezing here, preventing the final logs from being printed
after.reference.update(updated_data)
logger.info(
'Document updated: {}, Old data:{}, New data: {}'.format(
event.document,
after_data,
updated_data,
),
)
Stack trace
Here's the logs extracted from the GCP Logs Explorer.
downloaded-logs-20240228-171306.json