본문 바로가기

AI 개발

Firebase AI Logic + Gemini 실전 가이드 1편 — 개요, Firebase 세팅, 첫 API 호출까지

반응형

Gemini API를 앱에 붙이려면 API 키를 앱 코드에 넣어야 할 것 같습니다. 틀렸습니다. API 키가 앱 코드에 들어가면 누구나 추출해서 쓸 수 있습니다. Firebase AI Logic은 API 키를 서버에만 두고, 앱은 Firebase SDK로만 통신합니다. 백엔드 서버 없이, 신용카드 없이 시작할 수 있습니다.

[1편 핵심 요약]
→ Firebase AI Logic: 모바일·웹 앱에서 Gemini API 직접 호출 위한 Firebase 공식 SDK
→ 지원 플랫폼: Android(Kotlin/Java), iOS(Swift), Web(JS), Flutter(Dart), Unity, React Native
→ 두 가지 백엔드: Gemini Developer API(무료 티어) / Vertex AI Gemini API(GCP 청구)
→ 핵심 보안: API 키 앱 코드에 절대 넣지 않음 — Firebase 콘솔이 관리
→ 현재 최신 모델: gemini-3.1-flash-lite (권장) / gemini-2.5-flash
→ 주의: gemini-2.0-flash 2026년 6월 1일 종료 → 지금 마이그레이션 필요
→ Firebase BoM 버전: 34.12.0 (2026년 5월 기준)
→ 최소 요구사항: Android API Level 21+, iOS 15+

Firebase AI Logic이 뭔가

[Gemini API를 앱에 붙이는 3가지 방법]

1. Gemini API 직접 호출 (❌ 앱에선 위험):
   앱 코드 → API 키 포함 → Gemini API
   → API 키 앱에 하드코딩 → 역공학으로 추출 가능
   → 누구나 내 API 키로 Gemini 사용 가능

2. 직접 서버 구축 (복잡):
   앱 → 내 백엔드 서버 → Gemini API
   → 안전하지만 서버 구축·운영 비용 발생

3. Firebase AI Logic (✅ 권장):
   앱 SDK → Firebase 프록시 → Gemini API
   → API 키 Firebase 서버에만 존재
   → 앱 코드에 키 없음
   → 백엔드 서버 불필요
   → App Check로 인가된 앱만 접근 가능
[두 가지 백엔드 선택]

Gemini Developer API (시작 권장):
→ 무료 티어 — 신용카드 불필요
→ Google AI Studio에서 프로토타이핑
→ 소규모 앱, 개인 프로젝트
→ 나중에 Vertex AI로 전환 가능 (코드 한 줄)

Vertex AI Gemini API (프로덕션):
→ GCP 청구 계정 필요
→ 데이터 위치 요구사항 있는 경우
→ 기존 GCP/Vertex AI 스택 사용 팀
→ 엔터프라이즈 SLA 필요한 경우
→ 전환: GenerativeBackend.googleAI() → GenerativeBackend.vertexAI()

실전 1 — Firebase 프로젝트 세팅

Step 1: Firebase 프로젝트 생성

[Firebase 콘솔에서]

1. https://console.firebase.google.com 접속
2. "프로젝트 추가" 클릭
3. 프로젝트 이름 입력 (예: my-gemini-app)
4. Google Analytics 설정 (Firebase AI Logic에는 불필요 — 스킵 가능)
5. 프로젝트 생성 완료

또는 기존 Google Cloud 프로젝트에 Firebase 추가:
→ "Google Cloud 프로젝트에 Firebase 추가" 선택
→ 기존 프로젝트 선택

Step 2: AI Logic 활성화

[Firebase 콘솔에서]

1. 왼쪽 메뉴 → AI Services → AI Logic
2. "시작하기" 클릭
3. 가이드 워크플로우 실행:
   → 필요한 API 자동 활성화
   → Gemini API 키 자동 생성 (서버에만 저장)
4. API 프로바이더 선택:
   → "Gemini Developer API" 선택 (무료 시작)
5. 앱 등록 (다음 단계에서)

⚠️ 중요: 생성된 Gemini API 키를 앱 코드에 절대 넣지 말 것
→ Firebase가 키를 서버에서 관리
→ 앱은 Firebase SDK로만 통신

Step 3: 앱 등록 및 google-services.json 다운로드

[Android 앱 등록]

Firebase 콘솔 → 프로젝트 개요 → Android 아이콘 클릭

필수 입력:
→ Android 패키지 이름 (예: com.myapp.gemini)
→ 앱 닉네임 (선택)
→ SHA-1 (App Check 쓸 때 필요 — 지금은 스킵)

google-services.json 다운로드:
→ 앱 모듈 디렉토리에 복사
→ app/ 폴더 바로 아래 위치해야 함

my-android-project/
├── app/
│   ├── google-services.json  ← 여기
│   ├── src/
│   └── build.gradle.kts
├── build.gradle.kts
└── settings.gradle.kts

실전 2 — Android 프로젝트 설정 (Kotlin)

build.gradle.kts 설정

// 프로젝트 레벨 build.gradle.kts
plugins {
    id("com.google.gms.google-services") version "4.4.2" apply false
}
// 앱 레벨 build.gradle.kts (app/build.gradle.kts)
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.gms.google-services")  // Firebase 플러그인
}

android {
    compileSdk = 35
    defaultConfig {
        minSdk = 21  // Firebase AI Logic 최소 요구사항
        targetSdk = 35
    }
}

dependencies {
    // Firebase BoM — 버전 통합 관리 (2026년 5월 기준 최신)
    implementation(platform("com.google.firebase:firebase-bom:34.12.0"))

    // Firebase AI Logic — 버전 BoM이 관리하므로 생략
    implementation("com.google.firebase:firebase-ai")

    // 단일 응답용 (ListenableFuture)
    implementation("com.google.guava:guava:31.0.1-android")

    // 스트리밍 응답용 (Reactive Streams)
    implementation("org.reactivestreams:reactive-streams:1.0.4")
}
// settings.gradle.kts — Google 플러그인 저장소 추가
pluginManagement {
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
    }
}

실전 3 — 첫 Gemini API 호출

기본 텍스트 생성

// MainActivity.kt
import com.google.firebase.Firebase
import com.google.firebase.ai.ai
import com.google.firebase.ai.type.GenerativeBackend
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 1. GenerativeModel 초기화
        // GenerativeBackend.googleAI() = Gemini Developer API (무료 티어)
        // GenerativeBackend.vertexAI() = Vertex AI (GCP 청구)
        val model = Firebase.ai(backend = GenerativeBackend.googleAI())
            .generativeModel(
                modelName = "gemini-3.1-flash-lite",  // 최신 권장 모델
                // generationConfig = generationConfig { ... }  // 선택
            )

        // 2. 텍스트 생성 요청
        CoroutineScope(Dispatchers.Main).launch {
            try {
                val response = model.generateContent("AI 개발자로 성장하는 법을 3가지로 설명해줘")
                val text = response.text
                println(text)

            } catch (e: Exception) {
                println("에러: ${e.message}")
            }
        }
    }
}
// 모델 파라미터 설정
import com.google.firebase.ai.type.generationConfig

val generationConfig = generationConfig {
    temperature = 0.7f          // 창의성 (0.0~2.0, 기본 1.0)
    topP = 0.9f                 // 토큰 확률 필터링
    topK = 40                   // 상위 K 토큰만 샘플링
    maxOutputTokens = 1024      // 최대 출력 토큰
    stopSequences = listOf("###", "END")  // 정지 시퀀스
}

val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3.1-flash-lite",
        generationConfig = generationConfig
    )
// 시스템 지시문 추가
import com.google.firebase.ai.type.content

val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(
        modelName = "gemini-3.1-flash-lite",
        systemInstruction = content {
            text("당신은 Android 개발 전문가입니다. 항상 Kotlin 코드 예시와 함께 답변하세요.")
        }
    )

ViewModel로 올바르게 통합

// GeminiViewModel.kt — 프로덕션 패턴
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.firebase.Firebase
import com.google.firebase.ai.ai
import com.google.firebase.ai.type.GenerativeBackend
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

data class GeminiUiState(
    val isLoading: Boolean = false,
    val result: String = "",
    val error: String? = null
)

class GeminiViewModel : ViewModel() {

    private val _uiState = MutableStateFlow(GeminiUiState())
    val uiState: StateFlow<GeminiUiState> = _uiState

    // ViewModel 범위에서 모델 초기화 (액티비티 재생성에도 유지)
    private val model = Firebase.ai(backend = GenerativeBackend.googleAI())
        .generativeModel("gemini-3.1-flash-lite")

    fun generateContent(prompt: String) {
        viewModelScope.launch {
            _uiState.value = GeminiUiState(isLoading = true)

            try {
                val response = model.generateContent(prompt)
                _uiState.value = GeminiUiState(
                    result = response.text ?: "응답 없음"
                )
            } catch (e: Exception) {
                _uiState.value = GeminiUiState(
                    error = "오류: ${e.message}"
                )
            }
        }
    }
}

// MainActivity.kt — ViewModel 사용
class MainActivity : AppCompatActivity() {
    private val viewModel: GeminiViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleScope.launch {
            viewModel.uiState.collect { state ->
                when {
                    state.isLoading -> showLoading()
                    state.error != null -> showError(state.error)
                    state.result.isNotEmpty() -> showResult(state.result)
                }
            }
        }

        binding.btnGenerate.setOnClickListener {
            val prompt = binding.etPrompt.text.toString()
            viewModel.generateContent(prompt)
        }
    }
}

실전 4 — 웹 프로젝트 설정 (JavaScript)

Firebase 초기화

// firebase-config.js
import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend } from "firebase/ai";

// Firebase 콘솔에서 복사 (웹 앱 등록 후)
const firebaseConfig = {
  apiKey: "AIzaSy...",          // 일반 Firebase API 키 (Gemini 키 아님)
  authDomain: "my-app.firebaseapp.com",
  projectId: "my-app",
  storageBucket: "my-app.appspot.com",
  messagingSenderId: "123456789",
  appId: "1:123456789:web:abc123"
};

// Firebase 초기화
const app = initializeApp(firebaseConfig);

// Firebase AI Logic 초기화
// GoogleAIBackend = Gemini Developer API (무료 티어)
const ai = getAI(app, { backend: new GoogleAIBackend() });

// 모델 초기화
export const model = getGenerativeModel(ai, {
  model: "gemini-3.1-flash-lite"
});
// main.js — 기본 텍스트 생성
import { model } from "./firebase-config.js";

async function generateText(prompt) {
  try {
    const result = await model.generateContent(prompt);
    const response = result.response;
    const text = response.text();
    console.log(text);
    return text;
  } catch (error) {
    console.error("Gemini API 오류:", error);
    throw error;
  }
}

// 사용
document.getElementById("btn-generate").addEventListener("click", async () => {
  const prompt = document.getElementById("prompt-input").value;
  const result = await generateText(prompt);
  document.getElementById("result").textContent = result;
});
// npm 프로젝트에서 설치
// npm install firebase
// 또는
// yarn add firebase

// package.json 확인 — 최신 버전 사용
// "firebase": "^11.x.x"

실전 5 — 현재 지원 모델 정확한 목록

공식 문서 기준 (2026년 5월):

[Firebase AI Logic 지원 모델 — 현재]

✅ 사용 권장:
→ gemini-3.1-flash-lite  : 빠름, 저비용, 일반 태스크 권장
→ gemini-2.5-flash       : 균형, 멀티모달 지원
→ gemini-3.1-pro-preview : 고성능 (Preview)
→ gemini-3-flash-preview : Flash 계열 최신 (Preview)

⚠️ 곧 종료:
→ gemini-2.0-flash       : 2026년 6월 1일 종료
→ gemini-2.0-flash-lite  : 2026년 6월 1일 종료
→ (모든 Imagen 모델)     : 2026년 6월 24일 종료

❌ 이미 종료:
→ gemini-1.0-*, gemini-1.5-* : 이미 404 반환
→ gemini-2.5-flash-image-preview : 종료됨
// Remote Config로 모델명 동적 관리 (프로덕션 권장)
// 앱 재배포 없이 모델 교체 가능
import com.google.firebase.remoteconfig.FirebaseRemoteConfig

val remoteConfig = FirebaseRemoteConfig.getInstance()
remoteConfig.setDefaultsAsync(
    mapOf("gemini_model_name" to "gemini-3.1-flash-lite")
)

// 원격 값으로 모델 초기화
val modelName = remoteConfig.getString("gemini_model_name")
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel(modelName)

// 모델이 deprecate되면 Firebase 콘솔에서 Remote Config 값만 변경
// → 앱 업데이트 없이 즉시 반영

마무리

✅ 1편에서 한 것
→ Firebase 프로젝트 생성 + AI Logic 활성화
→ Android: BoM + firebase-ai 의존성 설정
→ Web: Firebase JS SDK 설치
→ GenerativeModel 초기화 + 첫 API 호출
→ ViewModel 패턴 올바른 통합
→ 현재 지원 모델 목록 확인

❌ 아직 안 한 것 (다음 편에서)
→ 스트리밍 응답 (실시간 타이핑 효과)
→ 멀티턴 채팅 구현
→ 이미지·오디오·PDF 입력 (멀티모달)
→ 구조화 출력 (JSON 응답)
→ 함수 호출 (Function Calling)
→ Firebase App Check (보안 강화)

⚠️ 지금 당장 확인할 것
→ gemini-2.0-flash 쓰고 있으면 6월 1일 전에 마이그레이션 필수
→ Imagen 모델 쓰고 있으면 6월 24일 전에 Nano Banana로 전환 필요

 

반응형