From 0f9448bf601e2984ed8ea5ed2356acf6e5954bfb Mon Sep 17 00:00:00 2001 From: Bradley McCallion Date: Fri, 6 Mar 2026 20:00:50 +0000 Subject: [PATCH 1/2] fix: bug where init isn't called with cors enabled --- src/firebase_functions/https_fn.py | 2 +- tests/test_https_fn.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/firebase_functions/https_fn.py b/src/firebase_functions/https_fn.py index 7e692de0..e2fe6d33 100644 --- a/src/firebase_functions/https_fn.py +++ b/src/firebase_functions/https_fn.py @@ -438,7 +438,7 @@ def on_request_wrapped(request: Request) -> Response: return _cross_origin( methods=options.cors.cors_methods, origins=options.cors.cors_origins, - )(func)(request) + )(_core._with_init(func))(request) return _core._with_init(func)(request) _util.set_func_endpoint_attr( diff --git a/tests/test_https_fn.py b/tests/test_https_fn.py index 1748b367..7a937e23 100644 --- a/tests/test_https_fn.py +++ b/tests/test_https_fn.py @@ -9,6 +9,7 @@ from werkzeug.test import EnvironBuilder from firebase_functions import core, https_fn +from firebase_functions.options import CorsOptions class TestHttps(unittest.TestCase): @@ -42,6 +43,34 @@ def init(): self.assertEqual(hello, "world") + def test_on_request_calls_init_function_with_cors(self): + app = Flask(__name__) + + hello = None + + @core.init + def init(): + nonlocal hello + hello = "world" + + func = Mock(__name__="example_func", return_value="OK") + + with app.test_request_context("/"): + environ = EnvironBuilder( + method="POST", + json={ + "data": {"test": "value"}, + }, + ).get_environ() + request = Request(environ) + decorated_func = https_fn.on_request( + cors=CorsOptions(cors_origins="*", cors_methods="GET") + )(func) + + decorated_func(request) + + self.assertEqual(hello, "world") + def test_on_call_calls_init_function(self): app = Flask(__name__) From e862fe1d9e199f8bbd665d10b08f78358cac95a5 Mon Sep 17 00:00:00 2001 From: Bradley McCallion Date: Fri, 8 May 2026 21:47:42 +0100 Subject: [PATCH 2/2] fix: make sure we only create the wrapper once at decoration time Previously we were doing redundant work on each call when this could be fixed a decoration time with no functional difference --- src/firebase_functions/https_fn.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/firebase_functions/https_fn.py b/src/firebase_functions/https_fn.py index e2fe6d33..7233e7f5 100644 --- a/src/firebase_functions/https_fn.py +++ b/src/firebase_functions/https_fn.py @@ -432,14 +432,19 @@ def example(request: Request) -> Response: options = HttpsOptions(**kwargs) def on_request_inner_decorator(func: _C1): + func_with_init = _core._with_init(func) + + if options.cors is not None: + wrapped_function = _cross_origin( + methods=options.cors.cors_methods, + origins=options.cors.cors_origins, + )(func_with_init) + else: + wrapped_function = func_with_init + @_functools.wraps(func) def on_request_wrapped(request: Request) -> Response: - if options.cors is not None: - return _cross_origin( - methods=options.cors.cors_methods, - origins=options.cors.cors_origins, - )(_core._with_init(func))(request) - return _core._with_init(func)(request) + return wrapped_function(request) _util.set_func_endpoint_attr( on_request_wrapped,