feat: add FirestoreSessionService for serverless session persistence#104
Closed
anmolg1997 wants to merge 1 commit intogoogle:mainfrom
Closed
feat: add FirestoreSessionService for serverless session persistence#104anmolg1997 wants to merge 1 commit intogoogle:mainfrom
anmolg1997 wants to merge 1 commit intogoogle:mainfrom
Conversation
Adds a BaseSessionService implementation backed by Google Cloud Firestore, providing persistent, serverless session storage suitable for Cloud Run, Cloud Functions, and other GCP environments. Key design decisions: - Events stored in Firestore subcollections to avoid 1MB doc limit - Three-tier state management (app/user/session) matching ADK conventions - Atomic state updates via Firestore transactions (race-condition safe) - Batch writes for bulk event deletion (500-doc chunks) - Server-side query limits via limit_to_last() for num_recent_events - google-cloud-firestore as an optional dependency Includes 19 unit tests with a lightweight in-memory Firestore mock. Fixes google#103 Ref: google/adk-python#3776, google/adk-python#4439
DeanChensj
approved these changes
Mar 31, 2026
| await self._update_user_state_transactional( | ||
| app_name, user_id, deltas["user"] | ||
| ) | ||
| if deltas["session"]: |
Collaborator
There was a problem hiding this comment.
Consider moving the session state update into a transaction, similar to how _update_app_state_transactional is implemented, to avoid potential race condition.
Collaborator
|
Please also fix the test failures |
9 tasks
ScottMansfield
added a commit
to ScottMansfield/adk-python
that referenced
this pull request
Apr 9, 2026
These updates are derived from @anmolg1997 PR on the community repo: google/adk-python-community#104
copybara-service bot
pushed a commit
to google/adk-python
that referenced
this pull request
Apr 14, 2026
END_PUBLIC Merge #5088 Adding support for Firestore for both session and memory storage. This started by copying the Firestore support from the Java ADK into the Python ADK and also takes inspiration from @anmolg1997's PR google/adk-python-community#104. It does things differently from both. Firestore contains a hierarchical set of data for sessions: ``` Hierarchy for sessions: adk-session ↳ <app name> ↳ users ↳ <user ID> ↳ sessions ↳ <session ID> ↳ events ↳ <event ID> Hierarchy for shared App/User state configurations: app_states ↳ <app name> user_states ↳ <app name> ↳ users ↳ <user ID> Hierarchy for memory: memories ↳ <memory ID> ``` The firestore memory service creates a top-level collection that hold indexed memories when sessions are added. ### Link to Issue or Description of Change This is from an existing customer request for firestore support. ### Testing Plan **Unit Tests:** - [x] I have added or updated unit tests for my change. - [x] All unit tests pass locally. ``` $ pytest tests/unittests/integrations/firestore/ ===================================== test session starts ====================================== platform darwin -- Python 3.11.14, pytest-9.0.2, pluggy-1.6.0 rootdir: /Users/scottmansfield/projects/adk-python configfile: pyproject.toml plugins: mock-3.15.1, xdist-3.8.0, langsmith-0.7.23, asyncio-1.3.0, anyio-4.13.0 asyncio: mode=Mode.AUTO, debug=False, asyncio_default_fixture_loop_scope=function, asyncio_default_test_loop_scope=function collected 29 items tests/unittests/integrations/firestore/test_firestore_memory_service.py ............. [ 44%] tests/unittests/integrations/firestore/test_firestore_session_service.py ................ [100%] ======================================= warnings summary ======================================= src/google/adk/features/_feature_decorator.py:72 /Users/scottmansfield/projects/adk-python/src/google/adk/features/_feature_decorator.py:72: UserWarning: [EXPERIMENTAL] feature FeatureName.PLUGGABLE_AUTH is enabled. check_feature_enabled() -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html ================================ 29 passed, 1 warning in 1.44s ================================= ``` **Manual End-to-End (E2E) Tests:** I created a demo app locally to test the session and memory storage with a real firebase instance. It successfully records sessions and memories, verified by manually checking the cloud console. Memory did require an index, which will be created by the user the first time the memory session is used. Firestore has a specific deep link that it will create to give the exact index needed. After that, memory worked fine. ### Checklist - [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document. - [x] I have performed a self-review of my own code. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have added tests that prove my fix is effective or that my feature works. - [x] New and existing unit tests pass locally with my changes. - [x] I have manually tested my changes end-to-end. - [x] Any dependent changes have been merged and published in downstream modules. COPYBARA_INTEGRATE_REVIEW=#5088 from ScottMansfield:feat/firestore 99efca5 PiperOrigin-RevId: 899328760
Author
|
Hey @DeanChensj — noticed that Firestore session (and memory) support landed in core Given that, I think this PR can be closed. Happy that the original design decisions here (subcollection-based events, transactional state updates, batch deletes) helped inform the final implementation. Thanks for the review and approval — appreciate the feedback throughout the process. Closing this one out. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
FirestoreSessionService— aBaseSessionServiceimplementation backed by Google Cloud Firestore, providing persistent, serverless session storage for Cloud Run, Cloud Functions, and other GCP environments where managing a SQL database is undesirable.This was originally submitted as google/adk-python#4439, where maintainer @rohityan directed it to this community repo.
Changes
src/google/adk_community/sessions/firestore_session_service.py— full implementationtests/unittests/sessions/test_firestore_session_service.py— 19 unit tests with lightweight in-memory Firestore mock (no GCP project required)src/google/adk_community/sessions/__init__.py— exportFirestoreSessionServicepyproject.toml— addfirestoreoptional dependency groupDesign Decisions
list_sessionsAsyncWriteBatchin 500-doc chunksnum_recent_eventslimit_to_last()instead of client-side slicingcreate_sessionreuses state returned from transactional updatesgoogle-cloud-firestoreimported at runtime with clear error messageAddresses Review Feedback
All issues raised by Gemini Code Assist on the original PR have been addressed:
create_sessionandappend_event→ Firestore transactionslist_sessions→ single shared fetchlimit_to_last()AsyncWriteBatchwith chunkingTest Plan
test_session_state_managementonmain)Fixes #103
Ref: google/adk-python#3776