반응형
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로 전환 필요
반응형
'AI 개발' 카테고리의 다른 글
| Firebase AI Logic + Gemini 실전 가이드 3편 — 웹(JavaScript/TypeScript) + Next.js 실전 (0) | 2026.05.19 |
|---|---|
| Firebase AI Logic + Gemini 실전 가이드 2편 — 스트리밍, 멀티턴 채팅, 멀티모달, 구조화 출력 (0) | 2026.05.19 |
| Repository Intelligence 완전 가이드 — AI가 코드 한 줄이 아니라 코드베이스 전체를 이해하는 법 (0) | 2026.05.19 |
| TurboQuant 심화 가이드 — PolarQuant + QJL 동작 원리부터 vLLM 실전 배포까지 (0) | 2026.05.19 |
| Aider 완전 가이드 — Git에 사는 AI 페어프로그래머, 모든 변경이 자동 커밋 (0) | 2026.05.19 |