firebase / firebase-functions-python

Apache License 2.0
138 stars 23 forks source link

Key error ['authtype'] in v0.3.0 when on_document_updated triggered from HTTP request #198

Closed andy-tmpt-me closed 7 months ago

andy-tmpt-me commented 7 months ago

In the following test scenario (derived from a production failure), an unauthed HTTP function creates and updates a simple document. The HTTP call succeeds, but the event handler fails repeatedly (attached screencap).

The code will succeed if I pin the firebase_functions requirement to 0.2.0 and redeploy.

image

Sample code:

requirements.txt

firebase_functions

main.py:

import logging
import time

from firebase_functions import https_fn, firestore_fn
from firebase_functions.firestore_fn import (
    Change,
    DocumentSnapshot,
    Event,
)
from google.cloud import firestore

logging.basicConfig(level=logging.INFO)
_log = logging.getLogger('f.test.main')
db: firestore.Client = firestore.Client()

@https_fn.on_request()
def create_test_doc(_) -> https_fn.Response:
    """Create a simple document, and then loop for 10 seconds doing a minor update"""
    start = time.time()
    _, doc_ref = db.collection('test').add({'value': 0, 'complete': False, 'created_at': firestore.SERVER_TIMESTAMP})
    _log.info(f'[HC]({elapsed(start)}s) Created test doc: {doc_ref.path}')

    do_updates(doc_ref.path)

    data = db.document(doc_ref.path).get().to_dict()
    message = f'[HR]({elapsed(start)}s) Test doc complete, document {doc_ref.path} data: {data}'
    _log.info(message)
    return https_fn.Response(message, status=200)

def do_updates(path):
    for i in range(10):
        doc = db.document(path).get()
        doc.reference.update({'value': i+1, 'updated_at': firestore.SERVER_TIMESTAMP})
        time.sleep(1)
    db.document(path).get().reference.update({'complete': True, 'updated_at': firestore.SERVER_TIMESTAMP})

@firestore_fn.on_document_updated(document="test/{doc_id}", timeout_sec=30)
def on_update_log_test_doc(event: Event[Change[DocumentSnapshot]]) -> None:
    """Listen for changes to the doc and output whether it is complete or not"""
    start = time.time()
    doc = db.document(event.document).get()
    doc_data = doc.to_dict()
    if doc_data.get('complete', False):
        _log.info(f'[UE]({elapsed(start)}s) Processing complete for {event.document} with data: {doc.to_dict()}')
    else:
        _log.info(f'[UE]({elapsed(start)}s) Processing incomplete for {event.document} with data: {doc.to_dict()}')

def elapsed(start):
    return round(time.time() - start, 2)
andy-tmpt-me commented 7 months ago

Ooops, looks like this is a duplicate of https://github.com/firebase/firebase-functions-python/issues/197 (logged a few hours previous). Hopefully the test case is helpful.

exaby73 commented 7 months ago

Closing in favor of https://github.com/firebase/firebase-functions-python/issues/194. I'll have a fix out soon

exaby73 commented 7 months ago

0.4.1 is released and should fix this