Skip to content

Commit b967be1

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

2 files changed

Lines changed: 199 additions & 0 deletions

File tree

372 KB
Loading
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
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+
> 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.
34+
35+
Add the following dependencies to your `pom.xml` (Maven) or `build.gradle` (Gradle), replacing `1.0.0` with your target ADK version:
36+
37+
### Maven
38+
39+
```xml
40+
<dependencies>
41+
<!-- ADK Core -->
42+
<dependency>
43+
<groupId>com.google.adk</groupId>
44+
<artifactId>google-adk</artifactId>
45+
<version>1.0.0</version>
46+
</dependency>
47+
<!-- Firestore Session Service -->
48+
<dependency>
49+
<groupId>com.google.adk</groupId>
50+
<artifactId>google-adk-firestore-session-service</artifactId>
51+
<version>1.0.0</version>
52+
</dependency>
53+
</dependencies>
54+
```
55+
56+
### Gradle
57+
58+
```gradle
59+
dependencies {
60+
// ADK Core
61+
implementation 'com.google.adk:google-adk:1.0.0'
62+
// Firestore Session Service
63+
implementation 'com.google.adk:google-adk-firestore-session-service:1.0.0'
64+
}
65+
```
66+
67+
## Example: Agent with Firestore Session Management
68+
69+
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.
70+
71+
```java
72+
import com.google.adk.agents.BaseAgent;
73+
import com.google.adk.agents.LlmAgent;
74+
import com.google.adk.agents.RunConfig;
75+
import com.google.adk.runner.FirestoreDatabaseRunner;
76+
import com.google.cloud.firestore.Firestore;
77+
import com.google.cloud.firestore.FirestoreOptions;
78+
import io.reactivex.rxjava3.core.Flowable;
79+
import java.util.Map;
80+
import com.google.adk.sessions.FirestoreSessionService;
81+
import com.google.adk.sessions.Session;
82+
import com.google.adk.tools.Annotations.Schema;
83+
import com.google.adk.tools.FunctionTool;
84+
import com.google.genai.types.Content;
85+
import com.google.genai.types.Part;
86+
import com.google.adk.events.Event;
87+
import java.util.Scanner;
88+
import static java.nio.charset.StandardCharsets.UTF_8;
89+
90+
public class YourAgentApplication {
91+
92+
public static void main(String[] args) {
93+
System.out.println("Starting YourAgentApplication...");
94+
95+
RunConfig runConfig = RunConfig.builder().build();
96+
String appName = "hello-time-agent";
97+
98+
BaseAgent timeAgent = initAgent();
99+
100+
// Initialize Firestore
101+
FirestoreOptions firestoreOptions = FirestoreOptions.getDefaultInstance();
102+
Firestore firestore = firestoreOptions.getService();
103+
104+
// Use FirestoreDatabaseRunner to persist session state
105+
FirestoreDatabaseRunner runner = new FirestoreDatabaseRunner(
106+
timeAgent,
107+
appName,
108+
firestore
109+
);
110+
111+
// Create a new session or load an existing one
112+
Session session = new FirestoreSessionService(firestore)
113+
.createSession(appName, "user1234", null, "12345")
114+
.blockingGet();
115+
116+
// Start interactive CLI
117+
try (Scanner scanner = new Scanner(System.in, UTF_8)) {
118+
while (true) {
119+
System.out.print("\\nYou > ");
120+
String userInput = scanner.nextLine();
121+
if ("quit".equalsIgnoreCase(userInput)) {
122+
break;
123+
}
124+
125+
Content userMsg = Content.fromParts(Part.fromText(userInput));
126+
Flowable<Event> events = runner.runAsync(session.userId(), session.id(), userMsg, runConfig);
127+
128+
System.out.print("\\nAgent > ");
129+
events.blockingForEach(event -> {
130+
if (event.finalResponse()) {
131+
System.out.println(event.stringifyContent());
132+
}
133+
});
134+
}
135+
}
136+
}
137+
138+
/** Mock tool implementation */
139+
@Schema(description = "Get the current time for a given city")
140+
public static Map<String, String> getCurrentTime(
141+
@Schema(name = "city", description = "Name of the city to get the time for") String city) {
142+
return Map.of(
143+
"city", city,
144+
"time", "The time is 10:30am."
145+
);
146+
}
147+
148+
private static BaseAgent initAgent() {
149+
return LlmAgent.builder()
150+
.name("hello-time-agent")
151+
.description("Tells the current time in a specified city")
152+
.instruction(\"""
153+
You are a helpful assistant that tells the current time in a city.
154+
Use the 'getCurrentTime' tool for this purpose.
155+
\""")
156+
.model("gemini-3.1-pro-preview")
157+
.tools(FunctionTool.create(YourAgentApplication.class, "getCurrentTime"))
158+
.build();
159+
}
160+
}
161+
```
162+
163+
## Configuration
164+
165+
> [!NOTE]
166+
> 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.
167+
168+
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.
169+
170+
### Environment-Specific Configuration
171+
172+
The library prioritizes environment-specific property files over the default settings using the following resolution order:
173+
174+
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`).
175+
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`.
176+
177+
Sample Property Settings:
178+
179+
```properties
180+
# Firestore collection name for storing session data
181+
adk.firestore.collection.name=adk-session
182+
# Google Cloud Storage bucket name for artifact storage
183+
adk.gcs.bucket.name=your-gcs-bucket-name
184+
# stop words for keyword extraction
185+
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
186+
```
187+
188+
> [!IMPORTANT]
189+
> `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.
190+
191+
192+
## Resources
193+
194+
- [Firestore Session Service](https://github.com/google/adk-java/tree/main/contrib/firestore-session-service):
195+
Source code for the Firestore Session Service.
196+
- [Spring Boot Google ADK + Firestore Example](https://github.com/mohan-ganesh/spring-boot-google-adk-firestore):
197+
An example project demonstrating how to build a Java-based Google ADK agent application using Cloud Firestore for session management.
198+
- [Firestore Session Service - DeepWiki](https://deepwiki.com/google/adk-java/4.3-firestore-session-service):
199+
Detailed description of Firestore integration in the Google ADK for Java.

0 commit comments

Comments
 (0)