Skip to content

Commit 4cf1140

Browse files
committed
Google Firestore: implement agent demonstrating session persistence using Firestore database for java adk
1 parent 7567175 commit 4cf1140

2 files changed

Lines changed: 202 additions & 0 deletions

File tree

372 KB
Loading
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
---
2+
catalog_title: Session Management with Firestore
3+
catalog_description: Session state management for ADK agents using Google Cloud Firestore
4+
catalog_icon: /integrations/assets/firestore-session.jpg
5+
catalog_tags: ["sessions", "database"]
6+
---
7+
8+
# Session Management with Google Cloud Firestore
9+
10+
<div class="language-support-tag">
11+
<span class="lst-supported">Supported in ADK</span><span class="lst-java">Java</span>
12+
</div>
13+
14+
[Google Cloud Firestore](https://cloud.google.com/firestore) is a flexible, scalable NoSQL cloud database to store and sync data for client- and server-side development.
15+
ADK provides a native integration for managing persistent agent session states using Firestore, allowing continuous multi-turn conversations without losing conversation history.
16+
17+
## Use cases
18+
19+
- **Customer Support Agents**: Maintain context across long-running support tickets, allowing the agent to remember past troubleshooting steps and preferences across multiple sessions.
20+
- **Personalized Assistants**: Build agents that accumulate knowledge about the user over time, personalizing future interactions based on historical conversations.
21+
- **Multi-modal Workflows**: Seamlessly handle complex use cases involving images, videos, and audio alongside text conversations, leveraging the built-in GCS artifact storage.
22+
- **Enterprise Chatbots**: Deploy highly reliable, conversational AI applications with production-grade persistence suitable for large-scale enterprise environments.
23+
24+
## Prerequisites
25+
26+
- A [Google Cloud Project](https://cloud.google.com/) with Firestore enabled
27+
- A [Firestore database](https://cloud.google.com/firestore/docs/setup) in your Google Cloud Project
28+
- Appropriate [Google Cloud credentials](https://cloud.google.com/docs/authentication/provide-credentials-adc) configured in your environment
29+
30+
## Install dependencies
31+
32+
!!! note
33+
34+
The `google-adk-firestore-session-service` version matches the core Google Agent ADK version. Ensure you use the same version for both libraries to guarantee compatibility.
35+
36+
Add the following dependencies to your `pom.xml` (Maven) or `build.gradle` (Gradle), replacing `1.0.0` with your target ADK version:
37+
38+
### Maven
39+
40+
```xml
41+
<dependencies>
42+
<!-- ADK Core -->
43+
<dependency>
44+
<groupId>com.google.adk</groupId>
45+
<artifactId>google-adk</artifactId>
46+
<version>1.0.0</version>
47+
</dependency>
48+
<!-- Firestore Session Service -->
49+
<dependency>
50+
<groupId>com.google.adk</groupId>
51+
<artifactId>google-adk-firestore-session-service</artifactId>
52+
<version>1.0.0</version>
53+
</dependency>
54+
</dependencies>
55+
```
56+
57+
### Gradle
58+
59+
```gradle
60+
dependencies {
61+
// ADK Core
62+
implementation 'com.google.adk:google-adk:1.0.0'
63+
// Firestore Session Service
64+
implementation 'com.google.adk:google-adk-firestore-session-service:1.0.0'
65+
}
66+
```
67+
68+
## Example: Agent with Firestore Session Management
69+
70+
Use `FirestoreDatabaseRunner` to encapsulate your agent and Firestore-backed session management. Here is a complete example of setting up a simple assistant agent that remembers conversation context across turns using a custom session ID.
71+
72+
```java
73+
import com.google.adk.agents.BaseAgent;
74+
import com.google.adk.agents.LlmAgent;
75+
import com.google.adk.agents.RunConfig;
76+
import com.google.adk.runner.FirestoreDatabaseRunner;
77+
import com.google.cloud.firestore.Firestore;
78+
import com.google.cloud.firestore.FirestoreOptions;
79+
import io.reactivex.rxjava3.core.Flowable;
80+
import java.util.Map;
81+
import com.google.adk.sessions.FirestoreSessionService;
82+
import com.google.adk.sessions.Session;
83+
import com.google.adk.tools.Annotations.Schema;
84+
import com.google.adk.tools.FunctionTool;
85+
import com.google.genai.types.Content;
86+
import com.google.genai.types.Part;
87+
import com.google.adk.events.Event;
88+
import java.util.Scanner;
89+
import static java.nio.charset.StandardCharsets.UTF_8;
90+
91+
public class YourAgentApplication {
92+
93+
public static void main(String[] args) {
94+
System.out.println("Starting YourAgentApplication...");
95+
96+
RunConfig runConfig = RunConfig.builder().build();
97+
String appName = "hello-time-agent";
98+
99+
BaseAgent timeAgent = initAgent();
100+
101+
// Initialize Firestore
102+
FirestoreOptions firestoreOptions = FirestoreOptions.getDefaultInstance();
103+
Firestore firestore = firestoreOptions.getService();
104+
105+
// Use FirestoreDatabaseRunner to persist session state
106+
FirestoreDatabaseRunner runner = new FirestoreDatabaseRunner(
107+
timeAgent,
108+
appName,
109+
firestore
110+
);
111+
112+
// Create a new session or load an existing one
113+
Session session = new FirestoreSessionService(firestore)
114+
.createSession(appName, "user1234", null, "12345")
115+
.blockingGet();
116+
117+
// Start interactive CLI
118+
try (Scanner scanner = new Scanner(System.in, UTF_8)) {
119+
while (true) {
120+
System.out.print("\\nYou > ");
121+
String userInput = scanner.nextLine();
122+
if ("quit".equalsIgnoreCase(userInput)) {
123+
break;
124+
}
125+
126+
Content userMsg = Content.fromParts(Part.fromText(userInput));
127+
Flowable<Event> events = runner.runAsync(session.userId(), session.id(), userMsg, runConfig);
128+
129+
System.out.print("\\nAgent > ");
130+
events.blockingForEach(event -> {
131+
if (event.finalResponse()) {
132+
System.out.println(event.stringifyContent());
133+
}
134+
});
135+
}
136+
}
137+
}
138+
139+
/** Mock tool implementation */
140+
@Schema(description = "Get the current time for a given city")
141+
public static Map<String, String> getCurrentTime(
142+
@Schema(name = "city", description = "Name of the city to get the time for") String city) {
143+
return Map.of(
144+
"city", city,
145+
"time", "The time is 10:30am."
146+
);
147+
}
148+
149+
private static BaseAgent initAgent() {
150+
return LlmAgent.builder()
151+
.name("hello-time-agent")
152+
.description("Tells the current time in a specified city")
153+
.instruction(\"""
154+
You are a helpful assistant that tells the current time in a city.
155+
Use the 'getCurrentTime' tool for this purpose.
156+
\""")
157+
.model("gemini-3.1-pro-preview")
158+
.tools(FunctionTool.create(YourAgentApplication.class, "getCurrentTime"))
159+
.build();
160+
}
161+
}
162+
```
163+
164+
## Configuration
165+
166+
!!! note
167+
168+
The Firestore Session Service supports properties file configuration. This allows you to easily target a dedicated Firestore database and define custom collection names for storing your agent session data.
169+
170+
You can customize your ADK application to use the Firestore session service by providing your own Firestore property settings, otherwise the library will use the default settings.
171+
172+
### Environment-Specific Configuration
173+
174+
The library prioritizes environment-specific property files over the default settings using the following resolution order:
175+
176+
1. **Environment Variable Override**: It first checks for an environment variable named `env`. If this variable is set (e.g., `env=dev`), it will attempt to load a properties file matching the template: `adk-firestore-{env}.properties` (e.g., `adk-firestore-dev.properties`).
177+
2. **Default Fallback**: If the `env` variable is not set, or the environment-specific file cannot be found, the library defaults to loading `adk-firestore.properties`.
178+
179+
Sample Property Settings:
180+
181+
```properties
182+
# Firestore collection name for storing session data
183+
adk.firestore.collection.name=adk-session
184+
# Google Cloud Storage bucket name for artifact storage
185+
adk.gcs.bucket.name=your-gcs-bucket-name
186+
# stop words for keyword extraction
187+
adk.stop.words=a,about,above,after,again,against,all,am,an,and,any,are,aren't,as,at,be,because,been,before,being,below,between,both,but,by,can't,cannot,could,couldn't,did,didn't,do,does,doesn't,doing,don't,down,during,each,few,for,from,further,had,hadn't,has,hasn't,have,haven't,having,he,he'd,he'll,he's,her,here,here's,hers,herself,him,himself,his,how,i,i'd,i'll,i'm,i've,if,in,into,is
188+
```
189+
190+
!!! important
191+
192+
`FirestoreDatabaseRunner` requires the `adk.gcs.bucket.name` property to be defined. This is because the runner internally initializes the `GcsArtifactService` to handle multi-modal artifact storage. If this property is missing or empty, the application will throw a `RuntimeException` during startup. This is used for storing artifacts like images, videos, audio files, etc. that are generated or processed by the agent.
193+
194+
195+
## Resources
196+
197+
- [Firestore Session Service](https://github.com/google/adk-java/tree/main/contrib/firestore-session-service):
198+
Source code for the Firestore Session Service.
199+
- [Spring Boot Google ADK + Firestore Example](https://github.com/mohan-ganesh/spring-boot-google-adk-firestore):
200+
An example project demonstrating how to build a Java-based Google ADK agent application using Cloud Firestore for session management.
201+
- [Firestore Session Service - DeepWiki](https://deepwiki.com/google/adk-java/4.3-firestore-session-service):
202+
Detailed description of Firestore integration in the Google ADK for Java.

0 commit comments

Comments
 (0)