Firebase Android SDK для Kotlin: полное руководство с примерами
1. Что это и зачем нужна
Firebase Android SDK — это мощный набор инструментов от Google, который предоставляет разработчикам готовую серверную инфраструктуру для мобильных приложений. Вместо того чтобы создавать и поддерживать собственный бэкенд, вы можете использовать Firebase для аутентификации пользователей, хранения данных в реальном времени, отправки push-уведомлений, аналитики и многого другого. Библиотека полностью интегрируется с экосистемой Android и написана на Kotlin с учетом всех современных практик разработки.
Основная цель Firebase — ускорить разработку приложений, избавив команды от необходимости писать сложный серверный код. Вы получаете готовые API для работы с базами данных (Cloud Firestore и Realtime Database), облачным хранилищем (Cloud Storage), аутентификацией (Firebase Auth), аналитикой (Google Analytics for Firebase) и даже машинным обучением (ML Kit). Все сервисы легко масштабируются и не требуют управления серверами.
Для Kotlin-разработчиков Firebase предлагает полностью типизированные API с поддержкой корутин, Flow и других современных возможностей языка. Это делает код более безопасным, читаемым и производительным. Библиотека используется в миллионах приложений по всему миру, включая такие гиганты, как The New York Times, Duolingo и Shazam.
2. Установка
Firebase Android SDK устанавливается через систему управления зависимостями Gradle. В отличие от pip или npm, здесь нет единой команды — нужно добавить несколько строк в файлы проекта.
Шаг 1: Добавление плагина Google Services
В корневой файл build.gradle.kts (уровень проекта) добавьте:
plugins {
id("com.google.gms.google-services") version "4.4.2" apply false
}
Шаг 2: Подключение Firebase BoM и зависимостей
В файл build.gradle.kts модуля приложения (app) добавьте:
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services")
}
dependencies {
// Firebase Bill of Materials — управляет версиями
implementation(platform("com.google.firebase:firebase-bom:33.1.0"))
// Основные модули Firebase
implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-auth")
implementation("com.google.firebase:firebase-firestore")
implementation("com.google.firebase:firebase-storage")
implementation("com.google.firebase:firebase-messaging")
implementation("com.google.firebase:firebase-config")
}
Шаг 3: Файл google-services.json
Скачайте файл google-services.json из консоли Firebase и поместите его в папку app/ вашего проекта. Этот файл содержит все ключи и идентификаторы для подключения к вашему проекту Firebase.
3. Быстрый старт — минимальный рабочий пример
Создадим простое приложение, которое логирует событие открытия экрана в Firebase Analytics.
// MainActivity.kt
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
class MainActivity : AppCompatActivity() {
private lateinit var firebaseAnalytics: FirebaseAnalytics
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Инициализация Firebase Analytics
firebaseAnalytics = Firebase.analytics
// Логирование события открытия экрана
val bundle = Bundle().apply {
putString(FirebaseAnalytics.Param.SCREEN_NAME, "MainScreen")
putString(FirebaseAnalytics.Param.SCREEN_CLASS, "MainActivity")
}
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle)
// Логирование пользовательского события
firebaseAnalytics.logEvent("app_started") {
param("user_type", "new")
param("app_version", BuildConfig.VERSION_NAME)
}
}
}
После запуска приложения вы сможете увидеть эти события в консоли Firebase в разделе Analytics → Events.
4. Основные методы/функции/классы
4.1. FirebaseAuth — аутентификация пользователей
Сигнатура: suspend fun FirebaseAuth.signInWithEmailAndPassword(email: String, password: String): AuthResult
Описание: Выполняет аутентификацию пользователя по email и паролю. Это корутинная версия метода, которая не блокирует UI-поток.
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.tasks.await
suspend fun loginUser(email: String, password: String): Result<AuthResult> {
return try {
val authResult = Firebase.auth.signInWithEmailAndPassword(email, password).await()
Result.success(authResult)
} catch (e: Exception) {
Result.failure(e)
}
}
// Использование в ViewModel
fun performLogin(email: String, password: String) {
viewModelScope.launch {
val result = loginUser(email, password)
result.onSuccess {
// Пользователь успешно вошел
Log.d("Auth", "User ID: ${it.user?.uid}")
}.onFailure { error ->
// Обработка ошибки
Log.e("Auth", "Login failed: ${error.message}")
}
}
}
4.2. FirebaseFirestore — работа с базой данных
Сигнатура: fun FirebaseFirestore.collection(collectionPath: String): CollectionReference
Описание: Возвращает ссылку на коллекцию в Cloud Firestore. Через эту ссылку можно добавлять, читать, обновлять и удалять документы.
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
data class User(
val name: String = "",
val email: String = "",
val age: Int = 0
)
// Добавление документа
suspend fun addUser(user: User): Result<DocumentReference> {
return try {
val docRef = Firebase.firestore.collection("users").add(user).await()
Result.success(docRef)
} catch (e: Exception) {
Result.failure(e)
}
}
// Чтение документа в реальном времени
fun observeUser(userId: String): Flow<User?> = callbackFlow {
val listener = Firebase.firestore.collection("users")
.document(userId)
.addSnapshotListener { snapshot, error ->
if (error != null) {
close(error)
return@addSnapshotListener
}
val user = snapshot?.toObject<User>()
trySend(user)
}
awaitClose { listener.remove() }
}
4.3. FirebaseStorage — загрузка файлов
Сигнатура: fun StorageReference.putFile(uri: Uri): UploadTask
Описание: Загружает файл из указанного URI в облачное хранилище Firebase. Возвращает UploadTask, который можно отслеживать для получения прогресса.
import com.google.firebase.storage.ktx.storage
import com.google.firebase.ktx.Firebase
suspend fun uploadImage(uri: Uri, userId: String): Result<String> {
return try {
val storageRef = Firebase.storage.reference
val imageRef = storageRef.child("images/${userId}/${uri.lastPathSegment}")
// Загрузка с отслеживанием прогресса
val uploadTask = imageRef.putFile(uri)
uploadTask.addOnProgressListener { taskSnapshot ->
val progress = (100.0 * taskSnapshot.bytesTransferred / taskSnapshot.totalByteCount)
Log.d("Storage", "Upload progress: $progress%")
}.await()
// Получение URL загруженного файла
val downloadUrl = imageRef.downloadUrl.await()
Result.success(downloadUrl.toString())
} catch (e: Exception) {
Result.failure(e)
}
}
4.4. FirebaseMessaging — push-уведомления
Сигнатура: fun FirebaseMessaging.subscribeToTopic(topic: String): Task<Void>
Описание: Подписывает устройство на указанную тему для получения push-уведомлений. Уведомления можно отправлять на все устройства, подписанные на тему.
import com.google.firebase.messaging.ktx.messaging
import com.google.firebase.ktx.Firebase
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
Log.d("FCM", "New token: $token")
// Отправляем токен на ваш сервер
sendTokenToServer(token)
}
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
// Обработка полученного уведомления
message.notification?.let { notification ->
showNotification(
title = notification.title ?: "",
body = notification.body ?: ""
)
}
}
private fun showNotification(title: String, body: String) {
val channelId = "default_channel"
val notification = NotificationCompat.Builder(this, channelId)
.setContentTitle(title)
.setContentText(body)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.build()
NotificationManagerCompat.from(this).notify(1001, notification)
}
}
// Подписка на тему
suspend fun subscribeToTopic(topic: String) {
try {
Firebase.messaging.subscribeToTopic(topic).await()
Log.d("FCM", "Subscribed to topic: $topic")
} catch (e: Exception) {
Log.e("FCM", "Subscription failed: ${e.message}")
}
}
4.5. FirebaseAnalytics — аналитика
Сигнатура: fun FirebaseAnalytics.logEvent(name: String, params: Bundle?)
Описание: Логирует пользовательское событие с указанным именем и параметрами. События отображаются в консоли Firebase Analytics.
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.analytics.ktx.logEvent
import com.google.firebase.ktx.Firebase
class AnalyticsHelper {
private val analytics = Firebase.analytics
fun trackPurchase(productId: String, price: Double, currency: String) {
analytics.logEvent(FirebaseAnalytics.Event.PURCHASE) {
param(FirebaseAnalytics.Param.ITEM_ID, productId)
param(FirebaseAnalytics.Param.PRICE, price)
param(FirebaseAnalytics.Param.CURRENCY, currency)
}
}
fun trackScreenView(screenName: String) {
analytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) {
param(FirebaseAnalytics.Param.SCREEN_NAME, screenName)
}
}
fun setUserProperties(userId: String, isPremium: Boolean) {
analytics.setUserId(userId)
analytics.setUserProperty("premium_user", isPremium.toString())
}
}
4.6. FirebaseRemoteConfig — удаленная конфигурация
Сигнатура: suspend fun FirebaseRemoteConfig.fetchAndActivate(): Boolean
Описание: Загружает и активирует удаленные конфигурации с сервера Firebase. Позволяет изменять поведение приложения без публикации обновления.
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfigSettings
import com.google.firebase.ktx.Firebase
class RemoteConfigManager {
private val remoteConfig = Firebase.remoteConfig
init {
val configSettings = remoteConfigSettings {
minimumFetchIntervalInSeconds = 3600 // 1 час
}
remoteConfig.setConfigSettingsAsync(configSettings)
// Значения по умолчанию
remoteConfig.setDefaultsAsync(
mapOf(
"welcome_message" to "Welcome!",
"feature_enabled" to false
)
)
}
suspend fun fetchConfig(): Boolean {
return try {
remoteConfig.fetchAndActivate().await()
} catch (e: Exception) {
Log.e("RemoteConfig", "Fetch failed: ${e.message}")
false
}
}
fun getWelcomeMessage(): String {
return remoteConfig.getString("welcome_message")
}
fun isFeatureEnabled(): Boolean {
return remoteConfig.getBoolean("feature_enabled")
}
}
4.7. FirebaseRealtimeDatabase — база данных реального времени
Сигнатура: fun DatabaseReference.setValue(value: Any?): Task<Void>
Описание: Записывает данные в указанную ссылку Realtime Database. Данные синхронизируются в реальном времени между всеми клиентами.
import com.google.firebase.database.ktx.database
import com.google.firebase.ktx.Firebase
class ChatManager {
private val database = Firebase.database
private val messagesRef = database.getReference("messages")
suspend fun sendMessage(chatId: String, message: ChatMessage) {
try {
val messageRef = messagesRef.child(chatId).push()
messageRef.setValue(message).await()
} catch (e: Exception) {
Log.e("Chat", "Send failed: ${e.message}")
}
}
fun observeMessages(chatId: String): Flow<List<ChatMessage>> = callbackFlow {
val listener = messagesRef.child(chatId)
.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val messages = snapshot.children.mapNotNull { child ->
child.getValue(ChatMessage::class.java)
}
trySend(messages)
}
override fun onCancelled(error: DatabaseError) {
close(error.toException())
}
})
awaitClose { messagesRef.removeEventListener(listener) }
}
}
data class ChatMessage(
val senderId: String = "",
val text: String = "",
val timestamp: Long = System.currentTimeMillis()
)
4.8. FirebaseFunctions — облачные функции
Сигнатура: suspend fun HttpsCallable.call(vararg args: Any?): HttpsCallableResult
Описание: Вызывает облачную функцию Firebase, написанную на Node.js или Python. Позволяет выполнять серверный код без управления инфраструктурой.
import com.google.firebase.functions.ktx.functions
import com.google.firebase.ktx.Firebase