Insight

February 28, 2025

Building Image Generation App with Firebase AI Logic (Nano Banana)

Building Image Generation App with Firebase AI Logic (Nano Banana)

Media generation applications have taken the tech world by storm, with millions of users creating, sharing, and exploring AI-generated content daily. From viral image creators to sophisticated design tools, these applications have become an integral part of our digital creative expression. This surge in AI-powered media creation has opened new possibilities for developers to build innovative applications that capture users’ imagination.



In this comprehensive guide, we’ll dive into building a cutting-edge image generation application using Firebase AI Logic. We’ll harness the power of Google’s Gemini model through Firebase’s secure and efficient infrastructure, creating an Android application that transforms text descriptions into stunning visual artwork. Whether you’re an experienced developer or just starting with AI integration, this tutorial will walk you through the essential steps to create a production-ready image generation app.

Firebase AI

Firebase AI Logic is a powerful service that provides access to Google’s state-of-the-art generative AI models, including both Gemini and Imagen. For developers looking to integrate AI capabilities directly into their mobile or web applications, Firebase AI Logic offers client SDKs specifically designed for this purpose.

The service supports multiple platforms through dedicated SDKs for Swift, Kotlin/Java, JavaScript, Dart, and Unity. What makes this particularly powerful is the multimodal capability of models like Gemini, which can process and generate content across different formats including text, images, PDFs, video, and audio.

To ensure secure implementation, Firebase AI Logic includes robust security features and can be coupled with Firebase App Check, providing protection against unauthorized usage and API abuse.

Implementation

Set up your Firebase project and connect your app to Firebase

Before diving into building your image generation application, it’s important to configure your Firebase project and link it to your app. While this step is foundational, it’s outside the primary scope of this blog. For detailed instructions, please refer to the official Firebase documentation.

Add the SDK

[versions]firebaseBom = "33.15.0"...[libraries]firebase-ai = { module = "com.google.firebase:firebase-ai" }firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" }...[plugins]
plugins { ... }android {    ...    defaultConfig {        minSdk = 21 // required to be at least 21        ...            }    ...}dependencies {    implementation(platform(libs.firebase.bom))    implementation(libs.firebase.ai)}

Once you’ve added the necessary dependencies, you can obtain a model like this:

fun generatorModel(): GenerativeModel = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel(    modelName = "...")

Do not add this Gemini API key into your app’s codebase.

Note that you can also use Vertex AI

fun generatorModel(): GenerativeModel = Firebase.ai(backend = GenerativeBackend.vertexAI()).generativeModel(    modelName = "...")

So to keep the things simple we can use the following function

fun generateGeminiModel(): GenerativeModel = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel(    modelName = "gemini-2.0-flash-preview-image-generation",    // Configure the model to respond with text and images    generationConfig = generationConfig {        responseModalities = listOf(ResponseModality.TEXT, ResponseModality.IMAGE)    })

Naturally, there’s no single model dedicated to image generation. You can explore the full list of available models here. Additionally, you have the flexibility to customize the model’s modalities to suit your needs. For instance, if you’re only interested in generating images, you can exclude the ‘Text’ modality.

Now we can define a generator function as :

suspend fun geminiImageGen(    prompt: String,    image: Bitmap?,    model: GenerativeModel = generatorModel()): Bitmap? {    val promptContext = content {        image?.let(::image)        text(prompt)    }    val generatedImageAsBitmap = model.generateContent(promptContext)    return generatedImageAsBitmap.image}val GenerateContentResponse.image: Bitmap?    get() {        val imagePart = candidates            .firstOrNull()            ?.content            ?.parts            ?.filterIsInstance<ImagePart>()            ?.firstOrNull()        return imagePart?.image    }

An ‘Image’ extension needed to be added to the code because, as of June 2025, the Firebase team had only provided a ‘text’ extension for GenerateContentResponse, which is internally defined as follows:

public val text: String? by lazy {  candidates.first().content.parts.filterIsInstance<TextPart>().joinToString(" ") { it.text }}

However, since the Firebase team did not provide support for the ‘image’ extension, we manually implemented it here for the sake of simplicity.



Get Oğuzhan Aslan’s stories in your inbox


Join Medium for free to get updates from this writer.





Subscribe



Alternatively, if you enable additional response modalities, you can access other components of the generated content. For instance, enabling both ‘text’ and ‘image’ modalities allows you to retrieve generated text alongside the image, as shown below.

suspend fun geminiImageGenAndText(    prompt: String,    image: Bitmap?,    model: GenerativeModel = generatorModel()): Pair<Bitmap?, String?> {    val promptContext = content {        image?.let(::image)        text(prompt)    }    val responseContent = model.generateContent(promptContext)    return responseContent.image to responseContent.text}

With these implementations in place, we’re now able to generate images seamlessly.





Press enter or click to view image in full size

Press enter or click to view image in full size

Image generation and editing using Gemini



Firebase also supports model generation using Imagen models, which typically yield higher quality results compared to Gemini models. However, access to the Imagen API is currently limited to users with a billing-enabled Firebase account.

@OptIn(PublicPreviewAPI::class)suspend fun imageGen(prompt: String): Bitmap {    val imagenModel = Firebase.ai(backend = GenerativeBackend.googleAI())            .imagenModel("imagen-3.0-generate-002")    val imageResponse = imagenModel.generateImages(prompt)    val image = imageResponse.images.first()    val bitmapImage = image.asBitmap()    return bitmapImage}@OptIn(PublicPreviewAPI::class)suspend fun imageGenMultiple(    prompt: String,    count: Int): List<Bitmap> {    val imagenModel = Firebase.ai(backend = GenerativeBackend.googleAI()).imagenModel(        modelName = "imagen-3.0-generate-002",        generationConfig = ImagenGenerationConfig(numberOfImages = count)    )    val imageResponse = imagenModel.generateImages(prompt)    return imageResponse.images.map { it.asBitmap() }

Multi-turn chat

It would be a missed opportunity to discuss generative models and LLMs without addressing multiturn conversations with AI models. With Gemini models, you can build interactive chat experiences where the model can modify images incrementally based on user prompts — step by step.

To create a chatbot or virtual assistant, it’s typically necessary to begin with a system instruction. This directive guides the model’s behavior, aligning its responses with your specific use case or desired personality.

fun generatorModel(    systemInstructions: String? = null): GenerativeModel = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel(    modelName = "...",    generationConfig = generationConfig { ... },    systemInstruction = systemInstructions?.let {        content {            text(systemInstructions)        }    })

To create a chat with the model you should do the following.

import com.google.firebase.ai.Chatval chat: Chat = model.startChat(  history = /** if you have history */)

And as usual, model Content contains roles as ‘model’, ‘user’. Even If you don’t pass a role, it is ‘user’ by default.

fun startChat(  messages: List<Message>) {    val model = generatorModel()    chat = model.startChat(        history = messages.map {            content(chatRole(it)) {                it.bitmap?.let(::image)                text(it.text)            }        }    )}private fun chatRole(it: Message) = when {    it.isFromMe -> "user"    else -> "model"}

After you create Chat instance, you can now send prompts to multi-turn chat.

private suspend fun sendMessage(    chat: Chat,    prompt: String): GenerateContentResponse = chat.sendMessage(prompt)private suspend fun sendMessage(    chat: Chat,    prompt: String,    image: Bitmap?): GenerateContentResponse = chat.sendMessage(    content {        image?.let(::image)        text(prompt)    })

and voalla! you have a multi turn chat now.





Press enter or click to view image in full size

Press enter or click to view image in full size

Image generation and editing from



Conclusion

And that’s it — you now have a working image generator application! Of course, this only scratches the surface of what Firebase AI Logic is capable of. There are many more features and functionalities beyond what we’ve covered here. To explore further, be sure to check out the official Firebase documentation.