diff --git a/firebase-ai/README.md b/firebase-ai/README.md
index 5ae40900b..c6cd38bb9 100644
--- a/firebase-ai/README.md
+++ b/firebase-ai/README.md
@@ -5,6 +5,8 @@ generative AI models (like Gemini) to build AI-powered features and applications
For more information about Firebase AI Logic, visit the [documentation](http://firebase.google.com/docs/ai-logic).
+
+
## Setup & Configuration
### Prerequisites
@@ -25,33 +27,40 @@ To try out this sample app, you need to use latest stable version of Android Stu
You can find the implementation for each feature by clicking on the links below:
-### Text / Chat
-- [Travel tips](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/TravelTipsViewModel.kt): The user wants the model to help a new traveler with travel tips
-- [Chatbot recommendations for courses](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/CourseRecommendationsViewModel.kt): A chatbot suggests courses for a performing arts program.
-- [Weather Chat](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/WeatherChatViewModel.kt): Use function calling to get the weather conditions for a specific US city on a specific date.
-- [Grounding with Google Search](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/GoogleSearchGroundingViewModel.kt): Use Grounding with Google Search to get responses based on up-to-date information from the web.
-- [Thinking](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ThinkingChatViewModel.kt): Gemini 2.5 Flash with dynamic thinking
-- [Server Prompt Templates - Gemini](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ServerPromptTemplateViewModel.kt): Generate an invoice using server prompt templates.
+### Gemini 3
+- [Translate text](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/TranslationViewModel.kt): Use Gemini 3.1 Flash-Lite to translate text
+- [SVG Generator](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/SvgViewModel.kt): Use Gemini 3.5 Flash to create SVG illustrations
+- [Gemini 3.1 Flash Image (Nano Banana 2)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBanana2ViewModel.kt): Generate and/or edit images using Nano Banana 2 preview
+- [Gemini 3 Pro Image (Nano Banana Pro)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBananaProViewModel.kt): Generate and/or edit images using Nano Banana Pro preview
-### Image analysis / generation
-- [Gemini 2.5 Flash Image (aka nanobanana)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ImageGenerationViewModel.kt): Generate and/or edit images using Gemini 2.5 Flash Image aka nanobanana
-- [SVG Generator](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/SvgViewModel.kt): Use Gemini 3 Flash preview to create SVG illustrations
-- [Blog post creator (Vertex AI)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ImageBlogCreatorViewModel.kt): Create a blog post from an image file stored in Cloud Storage.
+### Nano Banana
+- [Gemini 3.1 Flash Image (Nano Banana 2)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBanana2ViewModel.kt): Generate and/or edit images using Nano Banana 2 preview
+- [Gemini 3 Pro Image (Nano Banana Pro)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBananaProViewModel.kt): Generate and/or edit images using Nano Banana Pro preview
+- [Gemini 2.5 Flash Image (Nano Banana)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBananaViewModel.kt): Generate and/or edit images using Nano Banana (GA)
-### Audio analysis
-- [Audio Summarization](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/AudioSummarizationViewModel.kt): Summarize an audio file
+### Multimodal understanding
+- [Audio Summarization](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/AudioSummarizationViewModel.kt): Use Gemini 3.1 Flash Lite to summarize an audio file
+- [Summarize video](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/VideoSummarizationViewModel.kt): Summarize a video and extract important dialogue.
- [Translation from audio (Vertex AI)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/AudioTranslationViewModel.kt): Translate an audio file stored in Cloud Storage
-
-### Video analysis
+- [Blog post creator (Vertex AI)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ImageBlogCreatorViewModel.kt): Create a blog post from an image file stored in Cloud Storage.
+- [Document comparison (Vertex AI)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/DocumentComparisonViewModel.kt): Compare the contents of 2 documents stored in Cloud Storage.
- [Hashtags for a video (Vertex AI)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/VideoHashtagGeneratorViewModel.kt): Generate hashtags for a video ad stored in Cloud Storage
-- [Summarize video](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/VideoSummarizationViewModel.kt): Summarize a video and extract important dialogue.
-### Live API (Real-time bidrectional streaming)
-- [ForecastTalk](app/src/main/java/com/google/firebase/quickstart/ai/feature/live/StreamAudioViewModel.kt): Use bidirectional streaming to get information about weather conditions
-- [Gemini Live (Video input)](app/src/main/java/com/google/firebase/quickstart/ai/feature/live/StreamVideoViewModel.kt): Use bidirectional streaming to chat with Gemini using your phone's camera
+### Tools and function calling
+- [Grounding with Google Search](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/GoogleSearchGroundingViewModel.kt): Use Grounding with Google Search to get responses based on up-to-date information from the web.
+- [Weather Chat](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/WeatherChatViewModel.kt): Use function calling to get the weather conditions for a specific US city on a specific date.
+- [Gemini Live (audio input)](app/src/main/java/com/google/firebase/quickstart/ai/feature/live/StreamAudioViewModel.kt): Use bidirectional streaming to get information about weather conditions for a specific US city on a specific date
+- [Gemini Live (video input)](app/src/main/java/com/google/firebase/quickstart/ai/feature/live/StreamVideoViewModel.kt): Use bidirectional streaming to chat with Gemini using your phone's camera
+
+### Live API streaming
+- [Gemini Live (audio input)](app/src/main/java/com/google/firebase/quickstart/ai/feature/live/StreamAudioViewModel.kt): Use bidirectional streaming to get information about weather conditions for a specific US city on a specific date
+- [Gemini Live (video input)](app/src/main/java/com/google/firebase/quickstart/ai/feature/live/StreamVideoViewModel.kt): Use bidirectional streaming to chat with Gemini using your phone's camera
+
+### Server prompt templates
+- [Server Prompt Templates - Gemini](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ServerPromptTemplateViewModel.kt): Generate an invoice using server prompt templates.
-### Document (PDFs) analysis
-- [Document comparison (Vertex AI)](app/src/main/java/com/google/firebase/quickstart/ai/feature/text/DocumentComparisonViewModel.kt): Compare the contents of 2 documents in Cloud Storage.
+### Hybrid inference
+- [Hybrid Receipt Scanner](app/src/main/java/com/google/firebase/quickstart/ai/feature/hybrid/HybridInferenceViewModel.kt): Use hybrid inference to scan receipts and extract expense data on-device whenever possible.
## All samples
diff --git a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ThinkingChatViewModel.kt b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBanana2ViewModel.kt
similarity index 51%
rename from firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ThinkingChatViewModel.kt
rename to firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBanana2ViewModel.kt
index 8b59f9e2a..a768a5ea6 100644
--- a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ThinkingChatViewModel.kt
+++ b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBanana2ViewModel.kt
@@ -7,16 +7,25 @@ import com.google.firebase.ai.Chat
import com.google.firebase.ai.ai
import com.google.firebase.ai.type.Content
import com.google.firebase.ai.type.GenerativeBackend
+import com.google.firebase.ai.type.ResponseModality
import com.google.firebase.ai.type.generationConfig
-import com.google.firebase.ai.type.thinkingConfig
import com.google.firebase.quickstart.ai.ui.UiChatMessage
@Serializable
-object ThinkingChatRoute
+object NanoBanana2Route
-class ThinkingChatViewModel : ChatViewModel() {
+class NanoBanana2ViewModel : ChatViewModel() {
- override val initialPrompt: String = "Analogize photosynthesis and growing up."
+ override val initialPrompt: String = """
+ A photo of a glossy magazine cover, the minimal blue cover
+ has the large bold words Nano Banana. The text is in a serif
+ font and fills the view. No other text. In front of the text
+ there is a portrait of a person in a sleek and minimal dress.
+ She is playfully holding the number 2, which is the focal point.
+ Put the issue number and "Feb 2026" date in the corner along with
+ a barcode. The magazine is on a shelf against an orange plastered
+ wall, within a designer store.
+ """.trimIndent()
private val chat: Chat
@@ -24,12 +33,9 @@ class ThinkingChatViewModel : ChatViewModel() {
val generativeModel = Firebase.ai(
backend = GenerativeBackend.googleAI()
).generativeModel(
- modelName = "gemini-2.5-flash",
+ modelName = "gemini-3.1-flash-image-preview",
generationConfig = generationConfig {
- thinkingConfig = thinkingConfig {
- includeThoughts = true
- thinkingBudget = -1 // Dynamic Thinking
- }
+ responseModalities = listOf(ResponseModality.TEXT, ResponseModality.IMAGE)
}
)
chat = generativeModel.startChat()
diff --git a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBananaProViewModel.kt b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBananaProViewModel.kt
new file mode 100644
index 000000000..3fbe9aad6
--- /dev/null
+++ b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBananaProViewModel.kt
@@ -0,0 +1,51 @@
+package com.google.firebase.quickstart.ai.feature.text
+
+import kotlinx.serialization.Serializable
+
+import com.google.firebase.Firebase
+import com.google.firebase.ai.Chat
+import com.google.firebase.ai.ai
+import com.google.firebase.ai.type.Content
+import com.google.firebase.ai.type.GenerativeBackend
+import com.google.firebase.ai.type.ResponseModality
+import com.google.firebase.ai.type.generationConfig
+import com.google.firebase.quickstart.ai.ui.UiChatMessage
+
+@Serializable
+object NanoBananaProRoute
+
+class NanoBananaProViewModel : ChatViewModel() {
+
+ override val initialPrompt: String = """
+ Present a clear, 45° top-down isometric miniature 3D cartoon
+ scene of London, featuring its most iconic landmarks and
+ architectural elements. Use soft, refined textures with
+ realistic PBR materials and gentle, lifelike lighting and shadows.
+ Integrate the current weather conditions directly into the city
+ environment to create an immersive atmospheric mood. Use a clean,
+ minimalistic composition with a soft, solid-colored background.
+ At the top-center, place the title "London" in large bold text,
+ a prominent weather icon beneath it, then the date (small text)
+ and temperature (medium text). All text must be centered with
+ consistent spacing, and may subtly overlap the tops of the buildings.
+ """.trimIndent()
+
+ private val chat: Chat
+
+ init {
+ val generativeModel = Firebase.ai(
+ backend = GenerativeBackend.googleAI()
+ ).generativeModel(
+ modelName = "gemini-3-pro-image-preview",
+ generationConfig = generationConfig {
+ responseModalities = listOf(ResponseModality.TEXT, ResponseModality.IMAGE)
+ }
+ )
+ chat = generativeModel.startChat()
+ }
+
+ override suspend fun performSendMessage(prompt: Content, currentMessages: List) {
+ val response = chat.sendMessage(prompt)
+ validateAndDisplayResponse(response, currentMessages)
+ }
+}
diff --git a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ImageGenerationViewModel.kt b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBananaViewModel.kt
similarity index 94%
rename from firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ImageGenerationViewModel.kt
rename to firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBananaViewModel.kt
index 09c080215..b5b9ddf9a 100644
--- a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/ImageGenerationViewModel.kt
+++ b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/NanoBananaViewModel.kt
@@ -12,9 +12,9 @@ import com.google.firebase.ai.type.generationConfig
import com.google.firebase.quickstart.ai.ui.UiChatMessage
@Serializable
-object ImageGenerationRoute
+object NanoBananaRoute
-class ImageGenerationViewModel : ChatViewModel() {
+class NanoBananaViewModel : ChatViewModel() {
override val initialPrompt: String = """
Hi, can you create a 3d rendered image of a pig
diff --git a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/SvgViewModel.kt b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/SvgViewModel.kt
index bc6b4d7e2..130fa7e9b 100644
--- a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/SvgViewModel.kt
+++ b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/feature/text/SvgViewModel.kt
@@ -8,6 +8,7 @@ import com.google.firebase.Firebase
import com.google.firebase.ai.GenerativeModel
import com.google.firebase.ai.ai
import com.google.firebase.ai.type.GenerativeBackend
+import com.google.firebase.ai.type.ThinkingLevel
import com.google.firebase.ai.type.content
import com.google.firebase.ai.type.generationConfig
import com.google.firebase.ai.type.thinkingConfig
@@ -31,7 +32,7 @@ class SvgViewModel : ViewModel() {
generativeModel = Firebase.ai(
backend = GenerativeBackend.googleAI()
).generativeModel(
- modelName = "gemini-3-flash-preview",
+ modelName = "gemini-3.5-flash",
systemInstruction = content {
text(
"""
@@ -45,7 +46,7 @@ class SvgViewModel : ViewModel() {
},
generationConfig = generationConfig {
thinkingConfig {
- thinkingBudget = -1
+ thinkingLevel = ThinkingLevel.HIGH
}
}
)
@@ -58,6 +59,10 @@ class SvgViewModel : ViewModel() {
try {
val response = generativeModel.generateContent(prompt)
val newSvg = response.text
+ // Remove the ```xml [...] ``` around the svg
+ ?.removePrefix("```xml")
+ ?.removeSuffix("```")
+ ?.trimIndent()
if (newSvg != null) {
_uiState.value = SvgUiState.Success(listOf(newSvg) + currentSvgs)
} else {
diff --git a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/FirebaseAISamples.kt b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/FirebaseAISamples.kt
index af633b814..66adb0c14 100644
--- a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/FirebaseAISamples.kt
+++ b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/FirebaseAISamples.kt
@@ -1,35 +1,33 @@
package com.google.firebase.quickstart.ai.ui.navigation
-import com.google.firebase.quickstart.ai.feature.live.StreamAudioViewModel
-import com.google.firebase.quickstart.ai.feature.live.StreamVideoViewModel
import com.google.firebase.quickstart.ai.feature.hybrid.HybridInferenceRoute
import com.google.firebase.quickstart.ai.feature.hybrid.HybridInferenceViewModel
+import com.google.firebase.quickstart.ai.feature.live.StreamAudioViewModel
import com.google.firebase.quickstart.ai.feature.live.StreamRealtimeAudioRoute
import com.google.firebase.quickstart.ai.feature.live.StreamRealtimeVideoRoute
+import com.google.firebase.quickstart.ai.feature.live.StreamVideoViewModel
import com.google.firebase.quickstart.ai.feature.text.AudioSummarizationRoute
import com.google.firebase.quickstart.ai.feature.text.AudioSummarizationViewModel
import com.google.firebase.quickstart.ai.feature.text.AudioTranslationRoute
import com.google.firebase.quickstart.ai.feature.text.AudioTranslationViewModel
-import com.google.firebase.quickstart.ai.feature.text.CourseRecommendationsRoute
-import com.google.firebase.quickstart.ai.feature.text.CourseRecommendationsViewModel
import com.google.firebase.quickstart.ai.feature.text.DocumentComparisonRoute
import com.google.firebase.quickstart.ai.feature.text.DocumentComparisonViewModel
import com.google.firebase.quickstart.ai.feature.text.GoogleSearchGroundingRoute
import com.google.firebase.quickstart.ai.feature.text.GoogleSearchGroundingViewModel
import com.google.firebase.quickstart.ai.feature.text.ImageBlogCreatorRoute
import com.google.firebase.quickstart.ai.feature.text.ImageBlogCreatorViewModel
-import com.google.firebase.quickstart.ai.feature.text.ImageGenerationRoute
-import com.google.firebase.quickstart.ai.feature.text.ImageGenerationViewModel
+import com.google.firebase.quickstart.ai.feature.text.NanoBanana2Route
+import com.google.firebase.quickstart.ai.feature.text.NanoBanana2ViewModel
+import com.google.firebase.quickstart.ai.feature.text.NanoBananaProRoute
+import com.google.firebase.quickstart.ai.feature.text.NanoBananaProViewModel
+import com.google.firebase.quickstart.ai.feature.text.NanoBananaRoute
+import com.google.firebase.quickstart.ai.feature.text.NanoBananaViewModel
import com.google.firebase.quickstart.ai.feature.text.ServerPromptTemplateRoute
import com.google.firebase.quickstart.ai.feature.text.ServerPromptTemplateViewModel
import com.google.firebase.quickstart.ai.feature.text.SvgRoute
import com.google.firebase.quickstart.ai.feature.text.SvgViewModel
-import com.google.firebase.quickstart.ai.feature.text.ThinkingChatRoute
-import com.google.firebase.quickstart.ai.feature.text.ThinkingChatViewModel
import com.google.firebase.quickstart.ai.feature.text.TranslationRoute
import com.google.firebase.quickstart.ai.feature.text.TranslationViewModel
-import com.google.firebase.quickstart.ai.feature.text.TravelTipsRoute
-import com.google.firebase.quickstart.ai.feature.text.TravelTipsViewModel
import com.google.firebase.quickstart.ai.feature.text.VideoHashtagGeneratorRoute
import com.google.firebase.quickstart.ai.feature.text.VideoHashtagGeneratorViewModel
import com.google.firebase.quickstart.ai.feature.text.VideoSummarizationRoute
@@ -44,24 +42,15 @@ val FIREBASE_AI_SAMPLES = listOf(
route = TranslationRoute,
screenType = ScreenType.CHAT,
viewModelClass = TranslationViewModel::class,
- categories = listOf(Category.TEXT)
+ categories = listOf(Category.GEMINI3)
),
Sample(
- title = "Travel tips",
- description = "The user wants the model to help a new traveler" +
- " with travel tips",
- route = TravelTipsRoute,
- screenType = ScreenType.CHAT,
- viewModelClass = TravelTipsViewModel::class,
- categories = listOf(Category.TEXT),
- ),
- Sample(
- title = "Chatbot recommendations for courses",
- description = "A chatbot suggests courses for a performing arts program.",
- route = CourseRecommendationsRoute,
- screenType = ScreenType.CHAT,
- viewModelClass = CourseRecommendationsViewModel::class,
- categories = listOf(Category.TEXT),
+ title = "SVG Generator",
+ description = "Use Gemini 3.5 Flash to create SVG illustrations",
+ route = SvgRoute,
+ screenType = ScreenType.SVG,
+ viewModelClass = SvgViewModel::class,
+ categories = listOf(Category.GEMINI3)
),
Sample(
title = "Audio Summarization",
@@ -69,7 +58,15 @@ val FIREBASE_AI_SAMPLES = listOf(
route = AudioSummarizationRoute,
screenType = ScreenType.CHAT,
viewModelClass = AudioSummarizationViewModel::class,
- categories = listOf(Category.AUDIO),
+ categories = listOf(Category.MULTIMODAL_UNDERSTANDING),
+ ),
+ Sample(
+ title = "Summarize video",
+ description = "Summarize a video and extract important dialogue.",
+ route = VideoSummarizationRoute,
+ screenType = ScreenType.CHAT,
+ viewModelClass = VideoSummarizationViewModel::class,
+ categories = listOf(Category.MULTIMODAL_UNDERSTANDING)
),
Sample(
title = "Translation from audio (Vertex AI)",
@@ -77,7 +74,7 @@ val FIREBASE_AI_SAMPLES = listOf(
route = AudioTranslationRoute,
screenType = ScreenType.CHAT,
viewModelClass = AudioTranslationViewModel::class,
- categories = listOf(Category.AUDIO)
+ categories = listOf(Category.MULTIMODAL_UNDERSTANDING)
),
Sample(
title = "Blog post creator (Vertex AI)",
@@ -85,24 +82,39 @@ val FIREBASE_AI_SAMPLES = listOf(
route = ImageBlogCreatorRoute,
screenType = ScreenType.CHAT,
viewModelClass = ImageBlogCreatorViewModel::class,
- categories = listOf(Category.IMAGE)
+ categories = listOf(Category.MULTIMODAL_UNDERSTANDING)
+ ),
+ Sample(
+ title = "Gemini 3.1 Flash Image (Nano Banana 2)",
+ description = "Generate and/or edit images using Nano Banana 2 preview",
+ route = NanoBanana2Route,
+ screenType = ScreenType.CHAT,
+ viewModelClass = NanoBanana2ViewModel::class,
+ categories = listOf(Category.NANO_BANANA, Category.GEMINI3)
),
Sample(
- title = "Gemini 2.5 Flash Image (aka nanobanana)",
- description = "Generate and/or edit images using Gemini 2.5 Flash Image aka nanobanana",
- route = ImageGenerationRoute,
+ title = "Gemini 3 Pro Image (Nano Banana Pro)",
+ description = "Generate and/or edit images using Nano Banana Pro preview",
+ route = NanoBananaProRoute,
screenType = ScreenType.CHAT,
- viewModelClass = ImageGenerationViewModel::class,
- categories = listOf(Category.IMAGE)
+ viewModelClass = NanoBananaProViewModel::class,
+ categories = listOf(Category.NANO_BANANA, Category.GEMINI3)
+ ),
+ Sample(
+ title = "Gemini 2.5 Flash Image (Nano Banana)",
+ description = "Generate and/or edit images using Nano Banana (GA)",
+ route = NanoBananaRoute,
+ screenType = ScreenType.CHAT,
+ viewModelClass = NanoBananaViewModel::class,
+ categories = listOf(Category.NANO_BANANA)
),
Sample(
title = "Document comparison (Vertex AI)",
- description = "Compare the contents of 2 documents." +
- " Only supported by the Vertex AI Gemini API because the documents are stored in Cloud Storage",
+ description = "Compare the contents of 2 documents stored in Cloud Storage",
route = DocumentComparisonRoute,
screenType = ScreenType.CHAT,
viewModelClass = DocumentComparisonViewModel::class,
- categories = listOf(Category.DOCUMENT)
+ categories = listOf(Category.MULTIMODAL_UNDERSTANDING)
),
Sample(
title = "Hashtags for a video (Vertex AI)",
@@ -110,51 +122,43 @@ val FIREBASE_AI_SAMPLES = listOf(
route = VideoHashtagGeneratorRoute,
screenType = ScreenType.CHAT,
viewModelClass = VideoHashtagGeneratorViewModel::class,
- categories = listOf(Category.VIDEO)
+ categories = listOf(Category.MULTIMODAL_UNDERSTANDING)
),
Sample(
- title = "Summarize video",
- description = "Summarize a video and extract important dialogue.",
- route = VideoSummarizationRoute,
+ title = "Grounding with Google Search",
+ description = "Use Grounding with Google Search to get responses based on up-to-date information from the" +
+ " web.",
+ route = GoogleSearchGroundingRoute,
screenType = ScreenType.CHAT,
- viewModelClass = VideoSummarizationViewModel::class,
- categories = listOf(Category.VIDEO)
+ viewModelClass = GoogleSearchGroundingViewModel::class,
+ categories = listOf(Category.TOOLS_FC)
),
Sample(
- title = "ForecastTalk",
+ title = "Weather Chat",
+ description = "Use function calling to get the weather conditions" +
+ " for a specific US city on a specific date.",
+ route = WeatherChatRoute,
+ screenType = ScreenType.CHAT,
+ viewModelClass = WeatherChatViewModel::class,
+ categories = listOf(Category.TOOLS_FC)
+ ),
+ Sample(
+ title = "Gemini Live (audio input)",
description = "Use bidirectional streaming to get information about" +
" weather conditions for a specific US city on a specific date",
route = StreamRealtimeAudioRoute,
screenType = ScreenType.BIDI,
viewModelClass = StreamAudioViewModel::class,
- categories = listOf(Category.LIVE_API, Category.AUDIO, Category.FUNCTION_CALLING)
+ categories = listOf(Category.LIVE_API, Category.TOOLS_FC)
),
Sample(
- title = "Gemini Live (Video input)",
+ title = "Gemini Live (video input)",
description = "Use bidirectional streaming to chat with Gemini using your" +
" phone's camera",
route = StreamRealtimeVideoRoute,
screenType = ScreenType.BIDI_VIDEO,
viewModelClass = StreamVideoViewModel::class,
- categories = listOf(Category.LIVE_API, Category.VIDEO, Category.FUNCTION_CALLING)
- ),
- Sample(
- title = "Weather Chat",
- description = "Use function calling to get the weather conditions" +
- " for a specific US city on a specific date.",
- route = WeatherChatRoute,
- screenType = ScreenType.CHAT,
- viewModelClass = WeatherChatViewModel::class,
- categories = listOf(Category.TEXT, Category.FUNCTION_CALLING)
- ),
- Sample(
- title = "Grounding with Google Search",
- description = "Use Grounding with Google Search to get responses based on up-to-date information from the" +
- " web.",
- route = GoogleSearchGroundingRoute,
- screenType = ScreenType.CHAT,
- viewModelClass = GoogleSearchGroundingViewModel::class,
- categories = listOf(Category.TEXT)
+ categories = listOf(Category.LIVE_API, Category.TOOLS_FC)
),
Sample(
title = "Server Prompt Templates - Gemini",
@@ -163,23 +167,7 @@ val FIREBASE_AI_SAMPLES = listOf(
route = ServerPromptTemplateRoute,
screenType = ScreenType.SERVER_PROMPT,
viewModelClass = ServerPromptTemplateViewModel::class,
- categories = listOf(Category.TEXT),
- ),
- Sample(
- title = "Thinking",
- description = "Gemini 2.5 Flash with dynamic thinking",
- route = ThinkingChatRoute,
- screenType = ScreenType.CHAT,
- viewModelClass = ThinkingChatViewModel::class,
- categories = listOf(Category.TEXT)
- ),
- Sample(
- title = "SVG Generator",
- description = "Use Gemini 3 Flash preview to create SVG illustrations",
- route = SvgRoute,
- screenType = ScreenType.SVG,
- viewModelClass = SvgViewModel::class,
- categories = listOf(Category.IMAGE, Category.TEXT)
+ categories = listOf(Category.SERVER_PROMPTS),
),
Sample(
title = "Hybrid Receipt Scanner",
@@ -187,6 +175,7 @@ val FIREBASE_AI_SAMPLES = listOf(
route = HybridInferenceRoute,
screenType = ScreenType.HYBRID,
viewModelClass = HybridInferenceViewModel::class,
- categories = listOf(Category.TEXT, Category.IMAGE, Category.HYBRID)
+ categories = listOf(Category.HYBRID)
+
)
)
diff --git a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/MainMenuScreen.kt b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/MainMenuScreen.kt
index 74a9f9689..c34d0f89e 100644
--- a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/MainMenuScreen.kt
+++ b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/MainMenuScreen.kt
@@ -35,7 +35,6 @@ fun MainMenuScreen(
onSampleClicked: (Sample) -> Unit
) {
MenuScreen(
- filterTitle = "Filter by use case:",
filters = Category.entries.toList(),
samples = FIREBASE_AI_SAMPLES,
onSampleClicked = {
@@ -46,7 +45,6 @@ fun MainMenuScreen(
@Composable
fun MenuScreen(
- filterTitle: String,
filters: List,
samples: List,
onSampleClicked: (sample: Sample) -> Unit = {}
@@ -54,11 +52,11 @@ fun MenuScreen(
Column(
modifier = Modifier
.fillMaxSize()
- .padding(16.dp)
) {
var selectedCategory by rememberSaveable { mutableStateOf(filters.first()) }
- Text(text = filterTitle, style = MaterialTheme.typography.titleLarge)
- LazyRow {
+ LazyRow(
+ modifier = Modifier.padding(vertical = 8.dp)
+ ) {
items(filters) { capability ->
FilterChip(
onClick = { selectedCategory = capability },
@@ -77,21 +75,16 @@ fun MenuScreen(
} else {
null
},
- modifier = Modifier.padding(end = 8.dp)
+ modifier = Modifier.padding(horizontal = 4.dp)
)
}
}
- Text(
- text = "Samples",
- style = MaterialTheme.typography.titleLarge,
- modifier = Modifier.padding(top = 16.dp)
- )
val filteredSamples = samples.filter {
it.categories.contains(selectedCategory)
}
LazyVerticalGrid(
columns = GridCells.Adaptive(MIN_CARD_SIZE),
- modifier = Modifier
+ modifier = Modifier.padding(horizontal = 16.dp)
) {
items(filteredSamples) { sample ->
SampleItem(sample.title, sample.description, onItemClicked = {
diff --git a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/Sample.kt b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/Sample.kt
index af631a417..d800f0184 100644
--- a/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/Sample.kt
+++ b/firebase-ai/app/src/main/java/com/google/firebase/quickstart/ai/ui/navigation/Sample.kt
@@ -6,13 +6,12 @@ import kotlin.reflect.KClass
enum class Category(
val label: String
) {
- TEXT("Text"),
- IMAGE("Image"),
- VIDEO("Video"),
- AUDIO("Audio"),
- DOCUMENT("Document"),
- FUNCTION_CALLING("Function calling"),
- LIVE_API("Live API Streaming"),
+ GEMINI3("Gemini 3"),
+ NANO_BANANA("Nano Banana"),
+ MULTIMODAL_UNDERSTANDING("Multimodal understanding"),
+ TOOLS_FC("Tools and function calling"),
+ LIVE_API("Live API streaming"),
+ SERVER_PROMPTS("Server prompt templates"),
HYBRID("Hybrid inference")
}
diff --git a/firebase-ai/docs/result.png b/firebase-ai/docs/result.png
new file mode 100644
index 000000000..0e47c5158
Binary files /dev/null and b/firebase-ai/docs/result.png differ