From 2a06f941abb1f2c1f6ec98c123a615ec24cde27c Mon Sep 17 00:00:00 2001 From: Nilesh Patil <128893479+nileshpatil6@users.noreply.github.com> Date: Thu, 30 Apr 2026 00:45:38 +0530 Subject: [PATCH 1/2] fix(firestore): serialize session state as JSON to avoid Firestore reserved field name restrictions --- .../firestore/firestore_session_service.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/google/adk/integrations/firestore/firestore_session_service.py b/src/google/adk/integrations/firestore/firestore_session_service.py index 83b97c33c2..b2b3a16262 100644 --- a/src/google/adk/integrations/firestore/firestore_session_service.py +++ b/src/google/adk/integrations/firestore/firestore_session_service.py @@ -15,6 +15,7 @@ from __future__ import annotations import asyncio +import json from contextlib import asynccontextmanager from datetime import datetime from datetime import timezone @@ -203,7 +204,7 @@ async def create_session( "id": session_id, "appName": app_name, "userId": user_id, - "state": session_state, + "state": json.dumps(session_state), "createTime": now, "updateTime": now, "revision": 1, @@ -314,7 +315,10 @@ async def get_session( events.append(Event.model_validate(ed)) # Let's continue getting session. - session_state = data.get("state", {}) + raw_state = data.get("state", {}) + session_state = ( + json.loads(raw_state) if isinstance(raw_state, str) else raw_state + ) # Fetch shared state app_ref = self.client.collection(self.app_state_collection).document( @@ -407,7 +411,12 @@ async def list_sessions( data = doc.to_dict() if data: u_id = data["userId"] - s_state = data.get("state", {}) + raw_s_state = data.get("state", {}) + s_state = ( + json.loads(raw_s_state) + if isinstance(raw_s_state, str) + else raw_s_state + ) u_state = user_states_map.get(u_id, {}) merged = self._merge_state(app_state, u_state, s_state) @@ -555,7 +564,7 @@ async def _append_txn(transaction: firestore.AsyncTransaction) -> int: transaction.update( session_ref, { - "state": session_only_state, + "state": json.dumps(session_only_state), "updateTime": firestore.SERVER_TIMESTAMP, "revision": new_revision, }, From fe190ce7187b43a313303614b4280d28696bd9b4 Mon Sep 17 00:00:00 2001 From: Nilesh Patil <128893479+nileshpatil6@users.noreply.github.com> Date: Tue, 5 May 2026 18:15:49 +0530 Subject: [PATCH 2/2] fix(tests): update firestore state assertions to expect JSON-serialized string --- .../firestore/test_firestore_session_service.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unittests/integrations/firestore/test_firestore_session_service.py b/tests/unittests/integrations/firestore/test_firestore_session_service.py index 1445bfe0ef..f70fcd50a8 100644 --- a/tests/unittests/integrations/firestore/test_firestore_session_service.py +++ b/tests/unittests/integrations/firestore/test_firestore_session_service.py @@ -14,6 +14,7 @@ from __future__ import annotations +import json from unittest import mock from google.adk.events.event import Event @@ -117,7 +118,7 @@ async def test_create_session(mock_firestore_client): assert args[1]["id"] == session.id assert args[1]["appName"] == app_name assert args[1]["userId"] == user_id - assert args[1]["state"] == {} + assert json.loads(args[1]["state"]) == {} assert args[1]["createTime"] == firestore.SERVER_TIMESTAMP assert args[1]["updateTime"] == firestore.SERVER_TIMESTAMP @@ -324,8 +325,7 @@ async def test_append_event_with_state_delta(mock_firestore_client): transaction.update.assert_called_once() args, kwargs = transaction.update.call_args - # In modular Firestore configurations alignments, updating variables mock assertions core setups - assert args[1]["state"] == session.state + assert json.loads(args[1]["state"]) == session.state assert args[1]["updateTime"] == firestore.SERVER_TIMESTAMP