Skip to content

Commit 391c164

Browse files
authored
feat(firebase-ai): add Java and Kotlin code snippets (#645)
* feat: add Chat snippets * feat: add Function Calling snippets * feat: safety settings and model parameter snippets * feat: add system instructions snippets * chore: use gemini-2.5-flash and imagen-4.0-generate-001
1 parent 8133ae7 commit 391c164

File tree

8 files changed

+1209
-8
lines changed

8 files changed

+1209
-8
lines changed
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
package com.google.firebase.example.ailogic.java;
2+
3+
import androidx.lifecycle.ViewModel;
4+
5+
import com.google.common.util.concurrent.FutureCallback;
6+
import com.google.common.util.concurrent.Futures;
7+
import com.google.common.util.concurrent.ListenableFuture;
8+
import com.google.firebase.ai.FirebaseAI;
9+
import com.google.firebase.ai.GenerativeModel;
10+
import com.google.firebase.ai.java.ChatFutures;
11+
import com.google.firebase.ai.java.GenerativeModelFutures;
12+
import com.google.firebase.ai.type.Content;
13+
import com.google.firebase.ai.type.FunctionCallPart;
14+
import com.google.firebase.ai.type.FunctionResponsePart;
15+
import com.google.firebase.ai.type.GenerateContentResponse;
16+
import com.google.firebase.ai.type.Schema;
17+
import com.google.firebase.ai.type.TextPart;
18+
import com.google.firebase.ai.type.Tool;
19+
import com.google.firebase.ai.type.FunctionDeclaration;
20+
21+
import java.util.Arrays;
22+
import java.util.Collections;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.concurrent.Executor;
26+
import java.util.concurrent.Executors;
27+
28+
import kotlinx.serialization.json.JsonElement;
29+
import kotlinx.serialization.json.JsonElementKt;
30+
import kotlinx.serialization.json.JsonObject;
31+
import kotlinx.serialization.json.JsonPrimitive;
32+
33+
import org.reactivestreams.Publisher;
34+
import org.reactivestreams.Subscriber;
35+
import org.reactivestreams.Subscription;
36+
37+
public class CommonSnippets extends ViewModel {
38+
private Executor executor;
39+
private GenerativeModel ai = FirebaseAI.getInstance().generativeModel("gemini-2.5-flash");
40+
private GenerativeModelFutures model = GenerativeModelFutures.from(ai);
41+
42+
public void chat() {
43+
chatNonStreaming();
44+
chatStreaming();
45+
}
46+
47+
void chatNonStreaming() {
48+
// [START chat_non_streaming]
49+
// (optional) Create previous chat history for context
50+
Content.Builder userContentBuilder = new Content.Builder();
51+
userContentBuilder.setRole("user");
52+
userContentBuilder.addText("Hello, I have 2 dogs in my house.");
53+
Content userContent = userContentBuilder.build();
54+
55+
Content.Builder modelContentBuilder = new Content.Builder();
56+
modelContentBuilder.setRole("model");
57+
modelContentBuilder.addText("Great to meet you. What would you like to know?");
58+
Content modelContent = userContentBuilder.build();
59+
60+
List<Content> history = Arrays.asList(userContent, modelContent);
61+
62+
// Initialize the chat
63+
ChatFutures chat = model.startChat(history);
64+
65+
// Create a new user message
66+
Content.Builder messageBuilder = new Content.Builder();
67+
messageBuilder.setRole("user");
68+
messageBuilder.addText("How many paws are in my house?");
69+
70+
Content message = messageBuilder.build();
71+
72+
// Send the message
73+
ListenableFuture<GenerateContentResponse> response = chat.sendMessage(message);
74+
Futures.addCallback(
75+
response,
76+
new FutureCallback<GenerateContentResponse>() {
77+
@Override
78+
public void onSuccess(GenerateContentResponse result) {
79+
String resultText = result.getText();
80+
System.out.println(resultText);
81+
}
82+
83+
@Override
84+
public void onFailure(Throwable t) {
85+
t.printStackTrace();
86+
}
87+
},
88+
executor);
89+
// [END chat_non_streaming]
90+
}
91+
92+
void chatStreaming() {
93+
// [START chat_streaming]
94+
// (optional) Create previous chat history for context
95+
Content.Builder userContentBuilder = new Content.Builder();
96+
userContentBuilder.setRole("user");
97+
userContentBuilder.addText("Hello, I have 2 dogs in my house.");
98+
Content userContent = userContentBuilder.build();
99+
100+
Content.Builder modelContentBuilder = new Content.Builder();
101+
modelContentBuilder.setRole("model");
102+
modelContentBuilder.addText("Great to meet you. What would you like to know?");
103+
Content modelContent = userContentBuilder.build();
104+
105+
List<Content> history = Arrays.asList(userContent, modelContent);
106+
107+
// Initialize the chat
108+
ChatFutures chat = model.startChat(history);
109+
110+
// Create a new user message
111+
Content.Builder messageBuilder = new Content.Builder();
112+
messageBuilder.setRole("user");
113+
messageBuilder.addText("How many paws are in my house?");
114+
115+
Content message = messageBuilder.build();
116+
117+
// Send the message
118+
Publisher<GenerateContentResponse> streamingResponse = chat.sendMessageStream(message);
119+
120+
final String[] fullResponse = {""};
121+
122+
streamingResponse.subscribe(
123+
new Subscriber<GenerateContentResponse>() {
124+
125+
@Override
126+
public void onNext(GenerateContentResponse generateContentResponse) {
127+
String chunk = generateContentResponse.getText();
128+
fullResponse[0] += chunk;
129+
}
130+
131+
@Override
132+
public void onComplete() {
133+
System.out.println(fullResponse[0]);
134+
}
135+
136+
// ... other methods omitted for brevity
137+
138+
// [START_EXCLUDE]
139+
@Override
140+
public void onSubscribe(Subscription s) {
141+
}
142+
143+
@Override
144+
public void onError(Throwable t) {
145+
}
146+
147+
// [END_EXCLUDE]
148+
});
149+
// [END chat_streaming]
150+
}
151+
152+
public void functionCalling() {
153+
// [START function_calling_create_function_declaration]
154+
FunctionDeclaration fetchWeatherTool =
155+
new FunctionDeclaration(
156+
"fetchWeather",
157+
"Get the weather conditions for a specific city on a specific date.",
158+
Map.of(
159+
"location",
160+
Schema.obj(
161+
Map.of(
162+
"city", Schema.str("The city of the location."),
163+
"state", Schema.str("The US state of the location."))),
164+
"date",
165+
Schema.str(
166+
"The date for which to get the weather. "
167+
+ "Date must be in the format: YYYY-MM-DD.")),
168+
Collections.emptyList());
169+
// [END function_calling_create_function_declaration]
170+
171+
// [START function_calling_generate_function_call]
172+
String prompt = "What was the weather in Boston on October 17, 2024?";
173+
ChatFutures chatFutures = model.startChat();
174+
// Send the user's question (the prompt) to the model using multi-turn chat.
175+
ListenableFuture<GenerateContentResponse> response =
176+
chatFutures.sendMessage(new Content("user", List.of(new TextPart(prompt))));
177+
178+
ListenableFuture<JsonObject> handleFunctionCallFuture =
179+
Futures.transform(
180+
response,
181+
result -> {
182+
for (FunctionCallPart functionCall : result.getFunctionCalls()) {
183+
if (functionCall.getName().equals("fetchWeather")) {
184+
Map<String, JsonElement> args = functionCall.getArgs();
185+
JsonObject locationJsonObject = JsonElementKt.getJsonObject(args.get("location"));
186+
String city =
187+
JsonElementKt.getContentOrNull(
188+
JsonElementKt.getJsonPrimitive(locationJsonObject.get("city")));
189+
String state =
190+
JsonElementKt.getContentOrNull(
191+
JsonElementKt.getJsonPrimitive(locationJsonObject.get("state")));
192+
Location location = new Location(city, state);
193+
194+
String date =
195+
JsonElementKt.getContentOrNull(
196+
JsonElementKt.getJsonPrimitive(args.get("date")));
197+
return fetchWeather(location, date);
198+
}
199+
}
200+
return null;
201+
},
202+
Executors.newSingleThreadExecutor());
203+
// [END function_calling_generate_function_call]
204+
205+
// [START function_calling_pass_back_function_response]
206+
ListenableFuture<GenerateContentResponse> modelResponseFuture =
207+
Futures.transformAsync(
208+
handleFunctionCallFuture,
209+
// Send the response(s) from the function back to the model
210+
// so that the model can use it to generate its final response.
211+
functionCallResult ->
212+
chatFutures.sendMessage(
213+
new Content(
214+
"function",
215+
List.of(new FunctionResponsePart("fetchWeather", functionCallResult)))),
216+
Executors.newSingleThreadExecutor());
217+
218+
Futures.addCallback(
219+
modelResponseFuture,
220+
new FutureCallback<GenerateContentResponse>() {
221+
@Override
222+
public void onSuccess(GenerateContentResponse result) {
223+
if (result.getText() != null) {
224+
// Log the text response.
225+
System.out.println(result.getText());
226+
}
227+
}
228+
229+
@Override
230+
public void onFailure(Throwable t) {
231+
// handle error
232+
}
233+
},
234+
Executors.newSingleThreadExecutor());
235+
// [END function_calling_pass_back_function_response]
236+
}
237+
238+
// [START function_calling_write_function]
239+
// This function calls a hypothetical external API that returns
240+
// a collection of weather information for a given location on a given date.
241+
// `location` is an object of the form { city: string, state: string }
242+
public JsonObject fetchWeather(Location location, String date) {
243+
244+
// TODO(developer): Write a standard function that would call to an external weather API.
245+
246+
// For demo purposes, this hypothetical response is hardcoded here in the expected format.
247+
return new JsonObject(
248+
Map.of(
249+
"temperature",
250+
JsonElementKt.JsonPrimitive(38),
251+
"chancePrecipitation",
252+
JsonElementKt.JsonPrimitive("56%"),
253+
"cloudConditions",
254+
JsonElementKt.JsonPrimitive("partlyCloudy")
255+
)
256+
);
257+
}
258+
// [END function_calling_write_function]
259+
}
260+
261+
class Location {
262+
public String city;
263+
public String state;
264+
265+
public Location(String city, String state) {
266+
this.city = city;
267+
this.state = state;
268+
}
269+
}

firebase-ai/app/src/main/java/com/google/firebase/example/ailogic/java/GeneralViewModel.java

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)