### Kotlin Serialization: Contextual and Polymorphic Serialization Setup Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Provides an example of setting up contextual and polymorphic serialization for abstract classes and their subclasses using `SerializersModule`. This allows for more complex data structures to be serialized. ```kotlin @Serializable abstract class AbstractCity { abstract val name: String } @Serializable @SerialName("capital") data class Capital(override val name: String, val isSeatOfGovernment: Boolean) : AbstractCity() val module = SerializersModule { polymorphic(AbstractCity::class, AbstractCity.serializer()) { subclass(Capital::class, Capital.serializer()) } } val city = Capital("London", true) ``` -------------------------------- ### Kotlin Serialization: Gradle Plugin Setup Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Shows how to set up the Kotlin serialization plugin in a Gradle build file for multiplatform or JVM projects. This is necessary for using Kotlin serialization with Firebase. ```groovy plugins { kotlin("multiplatform") version "1.9.20" // or kotlin("jvm") or any other kotlin plugin kotlin("plugin.serialization") version "1.9.20" } ``` -------------------------------- ### Perform Cloud Firestore CRUD Operations in Kotlin Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Provides examples for basic Firestore operations including adding, setting, updating, retrieving, and deleting documents. It also demonstrates the use of data classes with serialization and configuring the Firestore emulator. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.firestore.* import kotlinx.serialization.Serializable @Serializable data class City( val name: String, val state: String, val country: String, val population: Long = 0, val capital: Boolean = false ) val firestore: FirebaseFirestore = Firebase.firestore suspend fun addCity(city: City): DocumentReference { return firestore.collection("cities").add(city) } suspend fun setCity(cityId: String, city: City) { firestore.collection("cities").document(cityId).set(city) } suspend fun updateCityPartial(cityId: String, city: City) { firestore.collection("cities").document(cityId).set(city, merge = true) } suspend fun getCity(cityId: String): City? { val snapshot = firestore.collection("cities").document(cityId).get() return if (snapshot.exists) { snapshot.data() } else null } suspend fun updateCityPopulation(cityId: String, newPopulation: Long) { firestore.collection("cities").document(cityId).updateFields { "population" to newPopulation "lastUpdated" to FieldValue.serverTimestamp } } suspend fun deleteCity(cityId: String) { firestore.collection("cities").document(cityId).delete() } fun useFirestoreEmulator() { firestore.useEmulator("10.0.2.2", 8080) } ``` -------------------------------- ### Install Firebase Kotlin SDK Dependencies in Gradle Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Add the necessary Firebase Kotlin SDK dependencies to your multiplatform Gradle project's build.gradle.kts file. This includes core Firebase App and specific service modules like Authentication, Cloud Firestore, and others. Ensure the Kotlin serialization plugin is also applied. ```kotlin plugins { kotlin("multiplatform") version "1.9.20" kotlin("plugin.serialization") version "1.9.20" } kotlin { sourceSets { commonMain.dependencies { // Core Firebase App implementation("dev.gitlive:firebase-app:2.4.0") // Authentication implementation("dev.gitlive:firebase-auth:2.4.0") // Cloud Firestore implementation("dev.gitlive:firebase-firestore:2.4.0") // Realtime Database implementation("dev.gitlive:firebase-database:2.4.0") // Cloud Storage implementation("dev.gitlive:firebase-storage:2.4.0") // Cloud Functions implementation("dev.gitlive:firebase-functions:2.4.0") // Analytics implementation("dev.gitlive:firebase-analytics:2.4.0") // Remote Config implementation("dev.gitlive:firebase-config:2.4.0") // Crashlytics implementation("dev.gitlive:firebase-crashlytics:2.4.0") // Cloud Messaging implementation("dev.gitlive:firebase-messaging:2.4.0") // Installations implementation("dev.gitlive:firebase-installations:2.4.0") // Performance Monitoring implementation("dev.gitlive:firebase-perf:2.4.0") } } } ``` -------------------------------- ### Disabling Firestore Persistence on Android Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Provides an example of how to access the underlying official Firebase SDK on Android to disable persistence for Cloud Firestore. This is done using extension properties available for platform-specific code. ```kotlin Firebase.firestore.android.firestoreSettings = FirebaseFirestoreSettings.Builder(Firebase.firestore.android.firestoreSettings) .setPersistenceEnabled(false) .build() ``` -------------------------------- ### Perform Basic CRUD and Configuration in Firebase Realtime Database Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Demonstrates standard database operations such as setting, pushing, updating, and deleting data. It also includes configuration for persistence, emulator usage, and connection state management. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.database.* import kotlinx.serialization.Serializable @Serializable data class Message( val text: String, val userId: String, val timestamp: Long = ServerValue.TIMESTAMP ) val database: FirebaseDatabase = Firebase.database val messagesRef: DatabaseReference = database.reference("messages") suspend fun setMessage(messageId: String, message: Message) { database.reference("messages/$messageId").setValue(message) } suspend fun pushMessage(message: Message): String { val newRef = messagesRef.push() newRef.setValue(message) return newRef.key!! } suspend fun updateUser(userId: String, updates: Map) { database.reference("users/$userId").updateChildren(updates) } suspend fun deleteMessage(messageId: String) { database.reference("messages/$messageId").removeValue() } fun configureDatabase() { database.setPersistenceEnabled(true) database.setLoggingEnabled(true) } fun useDatabaseEmulator() { database.useEmulator("10.0.2.2", 9000) } ``` -------------------------------- ### Configuring Cocoapods for iOS Tests Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Demonstrates how to configure Cocoapods in a `build.gradle` file to link necessary Firebase frameworks for iOS tests when using the Firebase Kotlin SDK. ```kotlin cocoapods { pod("FirebaseCore") // Repeat for Firebase pods required by your project, e.g FirebaseFirestore for the `firebase-firestore` module. } ``` -------------------------------- ### Firestore Queries with Infix Notation Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Illustrates how to write more readable Firestore queries using Kotlin's infix notation for operators like `equalTo`, `contains`, `and`, and `or`. This reduces boilerplate compared to traditional method calls. ```kotlin citiesRef.whereEqualTo("state", "CA") citiesRef.whereArrayContains("regions", "west_coast") citiesRef.where(Filter.and( Filter.equalTo("state", "CA"), Filter.or( Filter.equalTo("capital", true), Filter.greaterThanOrEqualTo("population", 1000000) ) )) //...becomes... citiesRef.where { "state" equalTo "CA" } citiesRef.where { "regions" contains "west_coast" } citiesRef.where { all( "state" equalTo "CA", any( "capital" equalTo true, "population" greaterThanOrEqualTo 1000000 ) ) } ``` -------------------------------- ### Perform Firestore CRUD with Serialization Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Demonstrates setting and retrieving data in Firestore using Kotlinx Serialization with custom serializers and modules. ```kotlin db.collection("cities").document("UK").set(AbstractCity.serializer(), city) { encodeDefaults = true serializersModule = module } val storedCity = db.collection("cities").document("UK").get().data(AbstractCity.serializer()) { serializersModule = module } ``` -------------------------------- ### Observe Real-time Data and Execute Queries Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Illustrates how to listen for real-time updates using Kotlin Flows and perform complex queries with ordering, filtering, and pagination. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.database.* import kotlinx.coroutines.flow.collect val database = Firebase.database suspend fun observeMessages() { database.reference("messages").valueEvents.collect { snapshot -> snapshot.children.forEach { child -> val message = child.value() println("Message: ${message.text}") } } } fun getMessagesByTimestamp(): Query { return database.reference("messages") .orderByChild("timestamp") .limitToLast(50) } fun getMessagesFromUser(userId: String): Query { return database.reference("messages") .orderByChild("userId") .equalTo(userId) } ``` -------------------------------- ### Initialize Firebase App in Kotlin Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Initialize the Firebase SDK in your Kotlin multiplatform project. This can be done automatically using google-services.json or manually by providing custom FirebaseOptions. The code demonstrates accessing the default app, initializing a named secondary app, retrieving named and all app instances, and deleting an app instance. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.FirebaseApp import dev.gitlive.firebase.FirebaseOptions import dev.gitlive.firebase.app import dev.gitlive.firebase.initialize // Access the default Firebase app (auto-initialized from google-services.json) val defaultApp: FirebaseApp = Firebase.app // Initialize with custom options val customApp = Firebase.initialize( context = null, // Pass Android Context on Android, null on other platforms options = FirebaseOptions( applicationId = "1:123456789:android:abcdef", apiKey = "AIzaSyDdVgKwhZl0sTTTLZ7iTmt1r3N2cJLnaDk", projectId = "my-project-id", databaseUrl = "https://my-project-id.firebaseio.com", storageBucket = "my-project-id.appspot.com", gcmSenderId = "123456789" ), name = "secondary-app" ) // Access a named Firebase app val namedApp = Firebase.app("secondary-app") // Get all Firebase app instances val allApps: List = Firebase.apps() // Delete a Firebase app instance suspend fun deleteApp() { namedApp.delete() } ``` -------------------------------- ### Firebase Remote Config: Fetch and Activate Configuration Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Demonstrates fetching and activating remote configuration values using the Firebase Kotlin SDK. It includes setting fetch intervals, timeouts, default values, and retrieving various data types. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.remoteconfig.* import kotlin.time.Duration.Companion.hours val remoteConfig: FirebaseRemoteConfig = Firebase.remoteConfig // Configure settings suspend fun configureRemoteConfig() { remoteConfig.settings { minimumFetchIntervalInSeconds = 3600 // 1 hour fetchTimeoutInSeconds = 60 } } // Set default values suspend fun setDefaults() { remoteConfig.setDefaults( "welcome_message" to "Welcome!", "feature_enabled" to true, "max_items" to 10, "price_multiplier" to 1.0 ) } // Fetch and activate suspend fun fetchAndActivate(): Boolean { return remoteConfig.fetchAndActivate() } // Fetch with minimum interval suspend fun fetchWithInterval() { remoteConfig.fetch(minimumFetchInterval = 1.hours) remoteConfig.activate() } // Get config values fun getConfigValues() { val welcomeMessage: String = remoteConfig["welcome_message"] val featureEnabled: Boolean = remoteConfig["feature_enabled"] val maxItems: Long = remoteConfig["max_items"] val priceMultiplier: Double = remoteConfig["price_multiplier"] println("Welcome: $welcomeMessage") println("Feature enabled: $featureEnabled") println("Max items: $maxItems") println("Price multiplier: $priceMultiplier") } // Get value with FirebaseRemoteConfigValue fun getValueDetails() { val value = remoteConfig.getValue("welcome_message") val stringValue = value.asString() val source = value.getSource() // DEFAULT, REMOTE, or STATIC } // Get all values fun getAllValues() { val allConfigs: Map = remoteConfig.all allConfigs.forEach { (key, value) -> println("$key = ${value.asString()}") } } // Get keys by prefix fun getFeatureFlags(): Set { return remoteConfig.getKeysByPrefix("feature_") } // Get config info fun getConfigInfo() { val info: FirebaseRemoteConfigInfo = remoteConfig.info println("Last fetch: ${info.lastFetchTimeMillis}") println("Fetch status: ${info.lastFetchStatus}") } // Reset all config suspend fun resetConfig() { remoteConfig.reset() } ``` -------------------------------- ### Create Authentication Credentials with Firebase Kotlin SDK Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Demonstrates how to generate AuthCredential objects for various providers including Email, Google, Facebook, GitHub, Twitter, and generic OAuth. It also includes helper functions for phone number verification and credential creation. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.auth.* val emailCredential = EmailAuthProvider.credential( email = "user@example.com", password = "securePassword123" ) val emailLinkCredential = EmailAuthProvider.credentialWithLink( email = "user@example.com", emailLink = "https://example.com/finishSignIn?link=..." ) val googleCredential = GoogleAuthProvider.credential( idToken = "google-id-token", accessToken = "google-access-token" ) val facebookCredential = FacebookAuthProvider.credential( accessToken = "facebook-access-token" ) val githubCredential = GithubAuthProvider.credential( token = "github-access-token" ) val twitterCredential = TwitterAuthProvider.credential( token = "twitter-access-token", secret = "twitter-token-secret" ) val oauthCredential = OAuthProvider.credential( providerId = "apple.com", idToken = "apple-id-token", accessToken = null, rawNonce = "random-nonce-string" ) suspend fun verifyPhone(phoneNumber: String, verificationProvider: PhoneVerificationProvider): AuthCredential { val phoneAuthProvider = PhoneAuthProvider() return phoneAuthProvider.verifyPhoneNumber(phoneNumber, verificationProvider) } fun createPhoneCredential(verificationId: String, smsCode: String): PhoneAuthCredential { val phoneAuthProvider = PhoneAuthProvider() return phoneAuthProvider.credential(verificationId, smsCode) } ``` -------------------------------- ### Define Data Models with Server Timestamps and GeoPoints Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Shows how to define data classes that incorporate server-side timestamps and native Firestore types like GeoPoint and DocumentReference. ```kotlin @Serializable data class Post( val timestamp: Timestamp = Timestamp.ServerTimestamp, val alternativeTimestamp = FieldValue.serverTimestamp, @Serializable(with = DoubleAsTimestampSerializer::class), val doubleTimestamp: Double = DoubleAsTimestampSerializer.serverTimestamp ) @Serializable data class PointOfInterest( val reference: DocumentReference, val location: GeoPoint ) val document = PointOfInterest( reference = Firebase.firestore.collection("foo").document("bar"), location = GeoPoint(51.939, 4.506) ) ``` -------------------------------- ### Update User Profile in Firebase Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Demonstrates how to update a user's profile information, including display name and photo URL, using the Firebase SDK. ```kotlin user.updateProfile(displayName = "Jane Q. User", photoURL = "https://example.com/jane-q-user/profile.jpg") ``` -------------------------------- ### Kotlin Serialization: Defining Serializable Data Classes Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Illustrates how to mark custom data classes as serializable using the `@Serializable` annotation. These classes can then be used with the Firebase Kotlin SDK for data storage and retrieval. ```kotlin @Serializable data class City(val name: String) ``` -------------------------------- ### Execute Advanced Field Updates and Queries Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Utilizes updateFields and startAtFieldValues to apply custom serialization settings to individual fields during Firestore operations. ```kotlin documentRef.updateFields { encodeDefaults = false serializersModule = module "field" to "value" "otherField".to(IntAsStringSerializer(), 1) withEncodeSettings { encodeDefaults = true serializersModule = otherModule "city" to abstractCity } } query.orderBy("field", "otherField", "city").startAtFieldValues { encodeDefaults = false serializersModule = module add("Value") add(1, IntAsStringSerializer()) withEncodeSettings { encodeDefaults = true serializersModule = otherModule add(abstractCity) } } ``` -------------------------------- ### Implement Real-time Firestore Updates with Kotlin Flows Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Shows how to observe Firestore documents and collections using Kotlin Flows. Includes handling metadata changes, tracking specific document lifecycle events (added, modified, removed), and checking data source origin (cache vs server). ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.firestore.* import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.map val firestore = Firebase.firestore fun observeCity(cityId: String): Flow { return firestore.collection("cities").document(cityId) .snapshots .map { snapshot -> if (snapshot.exists) snapshot.data() else null } } fun observeLargeCities(): Flow> { return firestore.collection("cities") .where { "population" greaterThan 1000000 } .orderBy("population", Direction.DESCENDING) .snapshots .map { snapshot -> snapshot.documents.map { it.data() } } } fun observeCitiesWithMetadata(): Flow { return firestore.collection("cities") .snapshots(includeMetadataChanges = true) } suspend fun trackChanges() { firestore.collection("cities").snapshots.collect { snapshot -> snapshot.documentChanges.forEach { change -> val city = change.document.data() when (change.type) { ChangeType.ADDED -> println("New city: ${city.name}") ChangeType.MODIFIED -> println("Modified city: ${city.name}") ChangeType.REMOVED -> println("Removed city: ${city.name}") } } } } suspend fun checkDataSource() { firestore.collection("cities").snapshots.collect { snapshot -> val metadata = snapshot.metadata if (metadata.isFromCache) { println("Data from cache") } if (metadata.hasPendingWrites) { println("Has pending writes") } } } ``` -------------------------------- ### Access Native Firebase SDKs in Kotlin Multiplatform Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Demonstrates how to access underlying native Firebase Firestore SDKs for Android, iOS, and JS platforms. This is useful when platform-specific configuration or advanced features not exposed by the common API are required. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.firestore.FirebaseFirestore fun configureFirestoreAndroid() { val firestore = Firebase.firestore // Access native Android FirebaseFirestore // firestore.android.firestoreSettings = FirebaseFirestoreSettings.Builder() // .setPersistenceEnabled(false) // .build() } fun configureFirestoreIOS() { val firestore = Firebase.firestore // Access native iOS FIRFirestore // firestore.ios.settings = FIRFirestoreSettings() } fun configureFirestoreJS() { val firestore = Firebase.firestore // Access native JS Firestore instance // firestore.js // Access web SDK } ``` -------------------------------- ### Firebase Cloud Storage File Operations (Kotlin) Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Provides functions for interacting with Firebase Cloud Storage using the Kotlin SDK. It covers uploading various data types, managing uploads with progress tracking, retrieving download URLs, metadata, deleting files, and listing storage contents. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.storage.* import kotlinx.coroutines.flow.collect import kotlin.time.Duration.Companion.minutes val storage: FirebaseStorage = Firebase.storage // Get reference to storage location val storageRef: StorageReference = storage.reference val imagesRef = storage.reference("images") val fileRef = storage.reference("images/photo.jpg") // Upload data (bytes) suspend fun uploadData(data: Data, path: String) { val ref = storage.reference(path) ref.putData(data, storageMetadata { contentType = "image/jpeg" setCustomMetadata("uploadedBy", "user123") }) } // Upload file suspend fun uploadFile(file: File, path: String) { val ref = storage.reference(path) ref.putFile(file, storageMetadata { contentType = "image/png" cacheControl = "max-age=3600" }) } // Resumable upload with progress tracking suspend fun uploadWithProgress(file: File, path: String) { val ref = storage.reference(path) val uploadTask = ref.putFileResumable(file, storageMetadata { contentType = "video/mp4" }) uploadTask.collect { when (it) { is Progress.Running -> { val percent = (100.0 * it.bytesTransferred.toLong() / it.totalByteCount.toLong()) println("Upload progress: $percent%") } is Progress.Paused -> println("Upload paused") } } } // Control upload (pause, resume, cancel) fun controlUpload(file: File, path: String) { val uploadTask = storage.reference(path).putFileResumable(file) // Pause upload uploadTask.pause() // Resume upload uploadTask.resume() // Cancel upload uploadTask.cancel() } // Get download URL suspend fun getDownloadUrl(path: String): String { return storage.reference(path).getDownloadUrl() } // Get file metadata suspend fun getMetadata(path: String): FirebaseStorageMetadata? { return storage.reference(path).getMetadata() } // Delete file suspend fun deleteFile(path: String) { storage.reference(path).delete() } // List files and folders suspend fun listFiles(path: String): ListResult { return storage.reference(path).listAll() } suspend fun listAllImages() { val result = storage.reference("images").listAll() // Files (items) result.items.forEach { ref -> println("File: ${ref.name}, Path: ${ref.path}") } // Folders (prefixes) result.prefixes.forEach { ref -> println("Folder: ${ref.name}") } } // Configure storage fun configureStorage() { storage.setMaxOperationRetryTime(2.minutes) storage.setMaxUploadRetryTime(10.minutes) } // Use emulator fun useStorageEmulator() { storage.useEmulator("10.0.2.2", 9199) } ``` -------------------------------- ### Realtime Database Transactions and OnDisconnect Operations (Kotlin) Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Demonstrates how to perform atomic updates using transactions and manage client presence with OnDisconnect operations in Firebase Realtime Database using the Kotlin SDK. It covers incrementing counters, setting online/offline status, and canceling disconnect operations. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.database.* import kotlinx.serialization.Serializable @Serializable data class Counter(val count: Int = 0) val database = Firebase.database // Transaction for atomic updates suspend fun incrementCounter(counterId: String) { database.reference("counters/$counterId") .runTransaction(Counter.serializer()) { currentData -> currentData.copy(count = currentData.count + 1) } } // OnDisconnect - operations executed when client disconnects suspend fun setupPresence(userId: String) { val userStatusRef = database.reference("status/$userId") val connectedRef = database.reference(".info/connected") // Set online status and setup offline status for disconnect userStatusRef.setValue(mapOf("state" to "online", "lastSeen" to ServerValue.TIMESTAMP)) // When disconnected, update status to offline userStatusRef.onDisconnect().setValue( mapOf("state" to "offline", "lastSeen" to ServerValue.TIMESTAMP) ) } // Cancel onDisconnect operation suspend fun cancelDisconnect(userId: String) { database.reference("status/$userId").onDisconnect().cancel() } // Remove value on disconnect suspend fun removeOnDisconnect(path: String) { database.reference(path).onDisconnect().removeValue() } // Update children on disconnect suspend fun updateOnDisconnect(userId: String) { database.reference("users/$userId").onDisconnect().updateChildren( mapOf( "online" to false, "lastSeen" to ServerValue.TIMESTAMP ) ) } ``` -------------------------------- ### Query Firestore Collections with Kotlin Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Demonstrates various Firestore query patterns including single/multiple condition filtering, ordering, pagination with cursors, and array-based queries. These functions utilize the FilterBuilder DSL to interact with Firestore collections asynchronously. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.firestore.* val firestore = Firebase.firestore val citiesRef = firestore.collection("cities") suspend fun getCitiesByState(state: String): List { val snapshot = citiesRef.where { "state" equalTo state }.get() return snapshot.documents.map { it.data() } } suspend fun getLargeCapitals(): List { val snapshot = citiesRef.where { all( "capital" equalTo true, "population" greaterThanOrEqualTo 1000000 ) }.get() return snapshot.documents.map { it.data() } } suspend fun getCaliforniaOrCapital(): List { val snapshot = citiesRef.where { any( "state" equalTo "CA", "capital" equalTo true ) }.get() return snapshot.documents.map { it.data() } } suspend fun getTopCitiesByPopulation(limit: Int): List { val snapshot = citiesRef .orderBy("population", Direction.DESCENDING) .limit(limit) .get() return snapshot.documents.map { it.data() } } suspend fun getNextPage(lastDocument: DocumentSnapshot, pageSize: Int): List { val snapshot = citiesRef .orderBy("population", Direction.DESCENDING) .startAfter(lastDocument) .limit(pageSize) .get() return snapshot.documents.map { it.data() } } suspend fun getCitiesInRegion(region: String): List { val snapshot = citiesRef.where { "regions" contains region }.get() return snapshot.documents.map { it.data() } } suspend fun getCitiesInAnyRegion(regions: List): List { val snapshot = citiesRef.where { "regions" containsAny regions }.get() return snapshot.documents.map { it.data() } } suspend fun getCitiesInStates(states: List): List { val snapshot = citiesRef.where { "state" inArray states }.get() return snapshot.documents.map { it.data() } } suspend fun getAllLandmarks(): QuerySnapshot { return firestore.collectionGroup("landmarks").get() } ``` -------------------------------- ### Firebase Authentication with Kotlin Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Handles user authentication using various methods like email/password, anonymous sign-in, Google OAuth, and custom tokens. It also provides functionality to observe authentication state changes and use the emulator for testing. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.auth.* import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect val auth: FirebaseAuth = Firebase.auth // Create user with email and password suspend fun createUser(email: String, password: String): FirebaseUser? { val result: AuthResult = auth.createUserWithEmailAndPassword(email, password) return result.user } // Sign in with email and password suspend fun signInWithEmail(email: String, password: String): FirebaseUser? { val result = auth.signInWithEmailAndPassword(email, password) return result.user } // Sign in anonymously suspend fun signInAnonymously(): FirebaseUser? { val result = auth.signInAnonymously() return result.user } // Sign in with Google credentials suspend fun signInWithGoogle(idToken: String, accessToken: String?): FirebaseUser? { val credential = GoogleAuthProvider.credential(idToken, accessToken) val result = auth.signInWithCredential(credential) return result.user } // Sign in with custom token (from your backend) suspend fun signInWithCustomToken(token: String): FirebaseUser? { val result = auth.signInWithCustomToken(token) return result.user } // Sign out suspend fun signOut() { auth.signOut() } // Get current user val currentUser: FirebaseUser? = auth.currentUser // Listen to authentication state changes val authStateFlow: Flow = auth.authStateChanged suspend fun observeAuthState() { auth.authStateChanged.collect { user -> if (user != null) { println("User signed in: ${user.uid}") } else { println("User signed out") } } } // Use emulator for testing fun useAuthEmulator() { auth.useEmulator("10.0.2.2", 9099) } ``` -------------------------------- ### Kotlin Coroutines: Flows for Asynchronous Data Streams Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Explains how asynchronous streams of values are represented using Flows. Flows are cold, meaning a new listener is attached each time a terminal operator is applied. Buffering and back-pressure behavior can be controlled using operators like `buffer` and `conflate`. Listeners are removed upon flow completion or cancellation. ```kotlin val snapshots: Flow ``` -------------------------------- ### Kotlin Serialization: Setting Custom Objects in Firestore Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Demonstrates how to set custom data class objects in Cloud Firestore using Kotlin serialization. It shows passing the serializer and configuring serialization behavior like `encodeDefaults`. ```kotlin db.collection("cities").document("LA").set(City.serializer(), city) { encodeDefaults = true } ``` -------------------------------- ### Track Analytics Events and User Properties with Firebase Kotlin SDK Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Provides methods for logging custom and predefined analytics events, managing user properties, setting default parameters, and configuring consent status. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.analytics.* import kotlin.time.Duration.Companion.minutes val analytics: FirebaseAnalytics = Firebase.analytics fun logCustomEvent() { analytics.logEvent("share_image") { param("image_name", "sunset.jpg") param("content_type", "image") param("item_id", "12345") } } fun logEventWithMap() { analytics.logEvent("purchase", mapOf( "item_id" to "SKU_12345", "item_name" to "Premium Plan", "price" to 9.99, "currency" to "USD" )) } fun logPredefinedEvents() { analytics.logEvent(AnalyticsEventConstants.SCREEN_VIEW) { param(AnalyticsParameterConstants.SCREEN_NAME, "Home") param(AnalyticsParameterConstants.SCREEN_CLASS, "MainActivity") } analytics.logEvent(AnalyticsEventConstants.ADD_TO_CART) { param(AnalyticsParameterConstants.ITEM_ID, "SKU_123") param(AnalyticsParameterConstants.ITEM_NAME, "T-Shirt") param(AnalyticsParameterConstants.PRICE, 19.99) } } fun setUserProperties() { analytics.setUserId("user_12345") analytics.setUserProperty("subscription_type", "premium") analytics.setUserProperty("favorite_category", "electronics") } fun setDefaultParameters() { analytics.setDefaultEventParameters(mapOf( "app_version" to "2.4.0", "platform" to "kotlin_multiplatform" )) } fun configureAnalytics() { analytics.setAnalyticsCollectionEnabled(true) analytics.setSessionTimeoutInterval(30.minutes) } suspend fun getSessionId(): Long? { return analytics.getSessionId() } fun resetData() { analytics.resetAnalyticsData() } fun setConsent() { analytics.setConsent { analyticsStorage = FirebaseAnalytics.ConsentStatus.GRANTED adStorage = FirebaseAnalytics.ConsentStatus.DENIED adPersonalization = FirebaseAnalytics.ConsentStatus.DENIED adUserData = FirebaseAnalytics.ConsentStatus.DENIED } } ``` -------------------------------- ### Perform Atomic Operations with Firestore Transactions and Batch Writes in Kotlin Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Demonstrates how to use Firestore transactions for atomic read/write operations and batch writes for atomic write-only operations. This ensures data consistency in concurrent operations. It requires the Firebase Firestore SDK. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.firestore.* val firestore = Firebase.firestore // Transaction - atomic read/write operations suspend fun transferPopulation(fromCityId: String, toCityId: String, amount: Long) { firestore.runTransaction { val fromRef = firestore.collection("cities").document(fromCityId) val toRef = firestore.collection("cities").document(toCityId) val fromSnapshot = get(fromRef) val toSnapshot = get(toRef) val fromCity = fromSnapshot.data() val toCity = toSnapshot.data() val newFromPopulation = fromCity.population - amount val newToPopulation = toCity.population + amount update(fromRef, fromCity.copy(population = newFromPopulation)) update(toRef, toCity.copy(population = newToPopulation)) } } // Batch write - atomic write-only operations suspend fun batchUpdateCities() { val batch = firestore.batch() val city1Ref = firestore.collection("cities").document("SF") val city2Ref = firestore.collection("cities").document("LA") val city3Ref = firestore.collection("cities").document("NYC") // Set a new document batch.set(city1Ref, City("San Francisco", "CA", "USA", 883305)) // Update fields in existing document batch.updateFields(city2Ref) { "population" to 4000000 "capital" to false } // Delete a document batch.delete(city3Ref) // Commit all operations atomically batch.commit() } // Transaction with custom serialization suspend fun incrementCounter(docId: String) { firestore.runTransaction { val docRef = firestore.collection("counters").document(docId) val snapshot = get(docRef) val currentCount = snapshot.get("count") updateFields(docRef) { "count" to (currentCount + 1) "lastUpdated" to FieldValue.serverTimestamp } } } ``` -------------------------------- ### Implement Polymorphic Serialization Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Configures sealed classes for polymorphic serialization, allowing the SDK to automatically discriminate between child classes using a custom type property. ```kotlin @Serializable @FirebaseClassDiscriminator("class") sealed class Parent { @Serializable @SerialName("child") data class Child( val property: Boolean ) : Parent } ``` -------------------------------- ### Firebase User Management with Kotlin Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Enables management of user profiles, including retrieving user properties, updating display names and photo URLs, changing passwords, sending email verification, and obtaining ID tokens. It also supports linking anonymous accounts, reauthentication, account deletion, and reloading user data. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.auth.* val user: FirebaseUser = Firebase.auth.currentUser!! // Get user properties val userId: String = user.uid val email: String? = user.email val displayName: String? = user.displayName val photoUrl: String? = user.photoURL val isAnonymous: Boolean = user.isAnonymous val isEmailVerified: Boolean = user.isEmailVerified // Update user profile suspend fun updateProfile() { user.updateProfile( displayName = "Jane Q. User", photoUrl = "https://example.com/jane-q-user/profile.jpg" ) } // Update password suspend fun updatePassword(newPassword: String) { user.updatePassword(newPassword) } // Send email verification suspend fun sendVerificationEmail() { user.sendEmailVerification() } // Get ID token for backend authentication suspend fun getIdToken(): String? { return user.getIdToken(forceRefresh = false) } // Get ID token with claims suspend fun getIdTokenWithClaims(): AuthTokenResult { val tokenResult = user.getIdTokenResult(forceRefresh = true) val claims: Map = tokenResult.claims val token: String? = tokenResult.token return tokenResult } // Link anonymous account with email credential suspend fun linkWithEmail(email: String, password: String): AuthResult { val credential = EmailAuthProvider.credential(email, password) return user.linkWithCredential(credential) } // Reauthenticate user (required before sensitive operations) suspend fun reauthenticate(email: String, password: String) { val credential = EmailAuthProvider.credential(email, password) user.reauthenticate(credential) } // Delete user account suspend fun deleteAccount() { user.delete() } // Reload user data from server suspend fun reloadUser() { user.reload() } ``` -------------------------------- ### Implement Type-Safe Data Handling with Kotlin Serialization in Firestore Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Shows how to use Kotlin serialization for type-safe data handling with custom classes, including support for server timestamps, GeoPoints, DocumentReferences, and polymorphic data. This requires the Firebase Firestore SDK and Kotlin serialization library. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.firestore.* import kotlinx.serialization.Serializable import kotlinx.serialization.SerialName // Basic serializable class @Serializable data class User( val name: String, val email: String, val age: Int = 0 ) // Class with server timestamp @Serializable data class Post( val title: String, val content: String, val timestamp: Timestamp = Timestamp.ServerTimestamp ) // Class with GeoPoint and DocumentReference @Serializable data class PointOfInterest( val name: String, val location: GeoPoint, val cityRef: DocumentReference ) // Polymorphic sealed class with custom discriminator @Serializable @FirebaseClassDiscriminator("type") sealed class Animal { abstract val name: String } @Serializable @SerialName("dog") data class Dog( override val name: String, val breed: String ) : Animal() @Serializable @SerialName("cat") data class Cat( override val name: String, val indoor: Boolean ) : Animal() val firestore = Firebase.firestore // Save with custom encode settings suspend fun saveWithSettings(user: User) { firestore.collection("users").document("user1").set(user) { encodeDefaults = true // Include default values } } // Save with explicit serializer suspend fun saveAnimal(animal: Animal) { firestore.collection("animals").add(Animal.serializer(), animal) } // Read with explicit serializer suspend fun getAnimal(id: String): Animal { val snapshot = firestore.collection("animals").document(id).get() return snapshot.data(Animal.serializer()) } // Create GeoPoint and DocumentReference suspend fun saveLocation() { val cityRef = firestore.collection("cities").document("SF") val poi = PointOfInterest( name = "Golden Gate Bridge", location = GeoPoint(37.8199, -122.4783), cityRef = cityRef ) firestore.collection("landmarks").add(poi) } ``` -------------------------------- ### Firebase HTTPS Callable Function with Operator Overloading Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Shows how to invoke a Firebase HTTPS Callable function using operator overloading for a more concise syntax, similar to how it might be done in the official Android SDK but with a different call signature. ```kotlin val addMessage = functions.getHttpsCallable("addMessage") //In the official android Firebase SDK this would be addMessage.call(...) addMessage(mapOf("text" to text, "push" to true)) ``` -------------------------------- ### Invoke HTTPS Callable Functions with Firebase Kotlin SDK Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Demonstrates how to define, call, and handle errors for Firebase Cloud Functions. It supports typed request/response objects, timeout configurations, regional targeting, and emulator usage. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.functions.* import kotlinx.serialization.Serializable import kotlin.time.Duration.Companion.seconds @Serializable data class AddMessageRequest(val text: String, val push: Boolean) @Serializable data class AddMessageResponse(val messageId: String) val functions: FirebaseFunctions = Firebase.functions val addMessage: HttpsCallableReference = functions.httpsCallable("addMessage") val addMessageWithTimeout = functions.httpsCallable("addMessage", timeout = 30.seconds) suspend fun callAddMessage(text: String): String { val result = addMessage(mapOf("text" to text, "push" to true)) return result.data() } suspend fun callTypedFunction(request: AddMessageRequest): AddMessageResponse { val result = addMessage(request) return result.data() } suspend fun callNoArgFunction(): String { val pingFunction = functions.httpsCallable("ping") val result = pingFunction() return result.data() } val functionsEurope = Firebase.functions("europe-west1") fun useFunctionsEmulator() { functions.useEmulator("10.0.2.2", 5001) } suspend fun callWithErrorHandling() { try { val result = addMessage(mapOf("text" to "Hello")) println("Success: ${result.data()}") } catch (e: FirebaseFunctionsException) { when (e.code) { FunctionsExceptionCode.UNAUTHENTICATED -> println("Not authenticated") FunctionsExceptionCode.INVALID_ARGUMENT -> println("Invalid argument: ${e.details}") FunctionsExceptionCode.UNAVAILABLE -> println("Service unavailable") else -> println("Error: ${e.code}") } } } ``` -------------------------------- ### Kotlin Coroutines: Suspending Functions for Async Operations Source: https://github.com/gitliveapp/firebase-kotlin-sdk/blob/master/README.md Demonstrates the use of suspending functions for asynchronous operations that return a single value. Unlike callback-based APIs, waiting for these functions is implicit. If immediate execution without waiting is needed, a new coroutine can be launched. ```kotlin suspend fun signInWithCustomToken(token: String): AuthResult ``` ```kotlin //TODO don't use GlobalScope GlobalScope.launch { Firebase.auth.signOut() } ``` -------------------------------- ### Firebase Crashlytics: Report Errors and Log Messages Source: https://context7.com/gitliveapp/firebase-kotlin-sdk/llms.txt Shows how to report non-fatal exceptions, log messages, set user identifiers, and custom keys to Firebase Crashlytics using the Firebase Kotlin SDK. It also covers enabling/disabling collection and handling unsent reports. ```kotlin import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.crashlytics.* val crashlytics: FirebaseCrashlytics = Firebase.crashlytics // Record non-fatal exception fun recordException(exception: Throwable) { crashlytics.recordException(exception) } // Log messages (visible in crash reports) fun logMessage(message: String) { crashlytics.log(message) } // Set user identifier fun setUser(userId: String) { crashlytics.setUserId(userId) } // Set custom keys fun setCustomKeys() { crashlytics.setCustomKey("screen", "checkout") crashlytics.setCustomKey("item_count", 5) crashlytics.setCustomKey("total_price", 99.99) crashlytics.setCustomKey("is_premium", true) } // Set multiple custom keys at once fun setMultipleKeys() { crashlytics.setCustomKeys(mapOf( "environment" to "production", "version" to "2.4.0", "build_number" to 123 )) } // Enable/disable collection fun configureCollection(enabled: Boolean) { crashlytics.setCrashlyticsCollectionEnabled(enabled) } // Check if crashed on previous execution fun checkPreviousCrash(): Boolean { return crashlytics.didCrashOnPreviousExecution() } // Manual crash report handling (when collection is disabled) fun handleUnsentReports() { // Send any unsent reports crashlytics.sendUnsentReports() // Or delete them crashlytics.deleteUnsentReports() } // Example: Wrap operations with crash logging fun performOperation() { try { crashlytics.log("Starting checkout process") crashlytics.setCustomKey("step", "payment") // Perform operation... crashlytics.log("Checkout completed successfully") } catch (e: Exception) { crashlytics.log("Checkout failed: ${e.message}") crashlytics.recordException(e) throw e } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.