Firebase Android SDK для Kotlin: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

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                    

Рекомендаций