firebase-kmp-sdk
1.2.3indexedReplica la API oficial de Firebase, entrega módulos modulares, integración con coroutines/Flow, serialización tipada (value<T>, toObject<T>, set<T>) y testing con emulator.
Replica la API oficial de Firebase, entrega módulos modulares, integración con coroutines/Flow, serialización tipada (value<T>, toObject<T>, set<T>) y testing con emulator.
Librería Kotlin Multiplatform que replica fielmente la API del Firebase Android SDK para Android, iOS y JavaScript.
El BOM (Bill of Materials) gestiona las versiones de todos los módulos automáticamente:
// build.gradle.kts (módulo compartido)
kotlin {
sourceSets {
commonMain.dependencies {
// BOM - gestiona las versiones automáticamente
implementation(platform("io.github.romancanoniero:firebase-bom:1.2.3"))
// Agrega los módulos que necesites SIN especificar versión
implementation("io.github.romancanoniero:firebase-core")
implementation("io.github.romancanoniero:firebase-auth")
implementation()
implementation()
implementation()
implementation()
implementation()
implementation()
}
}
}
Si prefieres especificar cada versión manualmente:
// build.gradle.kts (módulo compartido)
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.romancanoniero:firebase-core:1.2.3")
implementation("io.github.romancanoniero:firebase-auth:1.2.3")
implementation("io.github.romancanoniero:firebase-database:1.2.3")
implementation("io.github.romancanoniero:firebase-firestore:1.2.3")
implementation("io.github.romancanoniero:firebase-storage:1.2.3")
implementation("io.github.romancanoniero:firebase-functions:1.2.3")
implementation("io.github.romancanoniero:firebase-messaging:1.2.3")
implementation("io.github.romancanoniero:firebase-analytics:1.2.3")
}
}
}
Agrega los pods de Firebase en tu Podfile:
# iosApp/Podfile
target 'iosApp' do
use_frameworks!
pod 'FirebaseCore', '~> 10.29'
pod 'FirebaseAuth', '~> 10.29'
pod 'FirebaseDatabase', '~> 10.29'
pod 'FirebaseFirestore', '~> 10.29'
pod 'FirebaseStorage', '~> 10.29'
# ... otros pods según los módulos que uses
end
Las dependencias de Firebase JS se incluyen automáticamente via npm.
| Documento | Descripción |
|---|---|
| 🚀 Guía de Implementación | Setup paso a paso desde cero |
| 📖 API Reference |
// La inicialización es automática si tienes:
// - Android: google-services.json
// - iOS: GoogleService-Info.plist
val app = FirebaseApp.getInstance()
// O inicialización manual:
val options = FirebaseOptions.Builder()
.setApiKey("AIzaSy...")
.setApplicationId("1:123456789:android:abc123")
.setProjectId("my-project")
.setDatabaseUrl("https://my-project.firebaseio.com")
.setStorageBucket("my-project.appspot.com")
.build()
FirebaseApp.initializeApp(context, options) // Android
FirebaseApp.initializeApp(options)
storage = FirebaseStorage.getInstance()
imagesRef = storage.getReference()
photoRef = imagesRef.child()
uploadTask = photoRef.putFile()
uploadTask.progressFlow.collect { progress ->
percent = ( * progress.bytesTransferred / progress.totalByteCount).toInt()
println()
}
downloadUrl = photoRef.getDownloadUrl()
println()
photoRef.getFile()
metadata = photoRef.getMetadata()
println()
val functions = FirebaseFunctions.getInstance()
// Llamar función HTTPS
val result = functions.getHttpsCallable("myFunction").call(mapOf(
"param1" to "value1",
"param2" to 123
))
val data = result.data as Map<*, *>
println("Respuesta: $data")
val remoteConfig = FirebaseRemoteConfig.getInstance()
// Configurar defaults
remoteConfig.setDefaultsAsync(mapOf(
"welcome_message" to "Bienvenido!",
"feature_enabled" to false
))
// Fetch y activar
val success = remoteConfig.fetchAndActivate()
if (success) {
val welcomeMsg = remoteConfig.getString("welcome_message")
val featureEnabled = remoteConfig.getBoolean()
println()
}
val analytics = FirebaseAnalytics.getInstance()
// Log evento
analytics.logEvent("purchase", mapOf(
"item_id" to "SKU_123",
"item_name" to "Premium Plan",
"price" to 9.99
))
// Establecer propiedades de usuario
analytics.setUserProperty("subscription_type", "premium")
analytics.setUserId("user_12345")
val performance = FirebasePerformance.getInstance()
// Trace personalizado
val trace = performance.newTrace("my_operation")
trace.start()
// ... operación a medir ...
trace.putAttribute("result", "success")
trace.putMetric("items_processed", 42)
trace.stop()
// HTTP Metric
val httpMetric = performance.newHttpMetric(, )
httpMetric.start()
httpMetric.setHttpResponseCode()
httpMetric.setResponsePayloadSize()
httpMetric.stop()
Una de las características más potentes de esta librería son las extensiones tipadas que permiten serializar/deserializar objetos automáticamente usando kotlinx.serialization.
import kotlinx.serialization.Serializable
@Serializable
data class User(
val name: String,
email: String,
age: = ,
active: =
)
(
title: String,
content: String,
authorId: String,
likes: =
)
import com.iyr.firebase.database.*
val database = FirebaseDatabase.getInstance()
// Deserializar un objeto
val user = database.getReference().().value<User>()
users = database.getReference().().valueList<User>()
usersMap = database.getReference().().valueMap<User>()
name = snapshot.getString()
age = snapshot.getLong()
active = snapshot.getBoolean()
val user = User(name = "John", email = "john@example.com", age = 30)
// Guardar objeto tipado
database.getReference("users/user1").set(user)
// Actualizar con objeto tipado
database.getReference("users/user1").update(User(name = "Jane"))
// Push + set en una operación
val newRef = database.getReference("posts").pushValue(post)
println("Created: ${newRef.key}")
import com.iyr.firebase.firestore.*
val firestore = FirebaseFirestore.getInstance()
// Deserializar documento
val user = firestore.document("users/user1").get().toObject<User>()
// Deserializar query completa
val users = firestore.collection("users").get().toObjects<User>()
usersMap = firestore.collection().().toObjectsMap<User>()
firestore.collection().snapshots.collect { query ->
users = query.toObjects<User>()
}
val user = User(name = "John", email = "john@example.com")
// Add tipado
val docRef = firestore.collection().add(user)
firestore.document().(user)
firestore.document().update(User(name = ))
batch = firestore.batch()
batch.(userRef, user)
batch.update(postRef, postUpdate)
batch.commit()
firestore.runTransaction { tx ->
user = tx.(userRef).toObject<User>()!!
updated = user.copy(age = user.age + )
tx.(userRef, updated)
updated
}
# Android
./gradlew testDebugUnitTest
# iOS
./gradlew iosSimulatorArm64Test
# JavaScript
./gradlew jsNodeTest
npm install -g firebase-tools
firebase emulators:start --only auth,database,firestore,storage,functions
# Android
./gradlew connectedAndroidTest
# O el script incluido:
./run_integration_tests.sh
firebase-kmp-sdk/
├── firebase-core/ # FirebaseApp, FirebaseOptions
├── firebase-auth/ # Authentication
├── firebase-database/ # Realtime Database
├── firebase-firestore/ # Cloud Firestore
├── firebase-storage/ # Cloud Storage
├── firebase-functions/ # Cloud Functions
├── firebase-messaging/ # Push Notifications
├── firebase-analytics/ # Analytics
├── firebase-crashlytics/ # Crashlytics
├── firebase-remote-config/ # Remote Config
├── firebase-performance/ # Performance Monitoring
├── firebase-appcheck/
└── firebase-inappmessaging/
| Plataforma | Tecnología |
|---|---|
| Android | Wrapper sobre Firebase Android SDK oficial |
| iOS | Kotlin/Native cinterop → Firebase iOS SDK (Objective-C) |
Para desarrollo local:
./gradlew publishToMavenLocal
Los artefactos se publican en ~/.m2/repository/com/iyr/firebase/.
Copyright 2024 Roman Canoniero / IYR
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance the License.
You may obtain a copy of the License at
http:
Unless applicable law agreed to writing, software
distributed under the License distributed an BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express implied.
See the License the specific language governing permissions
limitations under the License.
¡Contribuciones son bienvenidas! Por favor:
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)⭐ Si este proyecto te es útil, considera darle una estrella en GitHub!
value<T>(), toObject<T>(), set<T>() con kotlinx.serialization| Módulo | Android | iOS | JS | Descripción |
|---|
firebase-bom | ✅ | ✅ | ✅ | Bill of Materials - Gestión de versiones |
firebase-core | ✅ | ✅ | ✅ | FirebaseApp, FirebaseOptions |
firebase-auth | ✅ | ✅ | ✅ | Autenticación completa (Email, Phone, OAuth) |
firebase-database | ✅ | ✅ | ✅ | Realtime Database |
firebase-firestore | ✅ | ✅ | ✅ | Cloud Firestore |
firebase-storage | ✅ | ✅ | ✅ | Cloud Storage |
firebase-functions | ✅ | ✅ | ✅ | Cloud Functions client |
firebase-messaging | ✅ | ✅ | ⚠️ | Push Notifications (FCM) |
firebase-analytics | ✅ | ✅ | ✅ | Google Analytics |
firebase-crashlytics | ✅ | ✅ | ❌ | Crashlytics |
firebase-remote-config | ✅ | ✅ | ✅ | Remote Config |
firebase-performance | ✅ | ✅ | ❌ | Performance Monitoring |
firebase-appcheck | ✅ | ✅ | ❌ | App Check |
firebase-inappmessaging | ✅ | ❌ | ❌ | In-App Messaging |
| Documentación completa de todas las funciones |
val auth = FirebaseAuth.getInstance()
// Crear usuario
val result = auth.createUserWithEmailAndPassword("email@example.com", "password123")
println("Usuario creado: ${result.user?.uid}")
// Iniciar sesión
val result = auth.signInWithEmailAndPassword("email@example.com", "password123")
val user = result.user
// Cerrar sesión
auth.signOut()
// Observar cambios de autenticación
auth.authStateChanges.collect { user ->
if (user != null) {
println("Conectado como: ${user.email}")
} else {
println("Desconectado")
}
}
// Autenticación anónima
val result = auth.signInAnonymously()
println("Usuario anónimo: ${result.user?.uid}")
val database = FirebaseDatabase.getInstance()
val usersRef = database.getReference("users")
// Escribir datos
usersRef.child(userId).setValue(mapOf(
"name" to "John Doe",
"email" to "john@example.com",
"age" to 30
))
// Leer una vez
val snapshot = usersRef.child(userId).get()
val name = snapshot.child("name").getValue() as? String
// Escuchar cambios en tiempo real
usersRef.child(userId).valueEvents.collect { snapshot ->
val userData = snapshot.getValue() as? Map<*, *>
println("Datos actualizados: $userData")
}
// Push (generar ID único)
val newPostRef = database.getReference("posts").push()
newPostRef.setValue(mapOf("title" to "Mi Post"))
println("Post ID: ${newPostRef.key}")
val firestore = FirebaseFirestore.getInstance()
// Agregar documento (ID auto-generado)
val docRef = firestore.collection("users").add(mapOf(
"name" to "Jane Doe",
"email" to "jane@example.com"
))
println("Documento creado: ${docRef.id}")
// Establecer documento (ID específico)
firestore.collection("users").document("user123").set(mapOf(
"name" to "John",
"active" to true
))
// Leer documento
val snapshot = firestore.document("users/user123").get()
if (snapshot.exists()) {
val data = snapshot.getData()
println("Nombre: ${data?.get("name")}")
}
// Query con filtros
val activeUsers = firestore.collection("users")
.whereEqualTo("active", true)
.orderBy("name")
.limit(10)
.get()
activeUsers.documents.forEach { doc ->
println("${doc.id}: ${doc.getData()}")
}
// Escuchar cambios en tiempo real
firestore.collection("messages")
.whereEqualTo("roomId", "room123")
.snapshots
.collect { querySnapshot ->
querySnapshot.documentChanges.forEach { change ->
when (change.type) {
DocumentChange.Type.ADDED -> println("Nuevo mensaje")
DocumentChange.Type.MODIFIED -> println("Mensaje editado")
DocumentChange.Type.REMOVED -> println("Mensaje eliminado")
}
}
}
| Extensión | Descripción |
|---|
snapshot.value<T>() | Deserializa a objeto @Serializable |
snapshot.valueList<T>() | Deserializa hijos a List |
snapshot.valueMap<T>() | Deserializa hijos a Map<String, T> |
ref.set<T>(obj) | Guarda objeto serializado |
ref.update<T>(obj) | Actualiza con objeto serializado |
ref.pushValue<T>(obj) | Push + set, retorna referencia |
obj.toFirebaseMap() | Convierte @Serializable a Map |
| Extensión | Descripción |
|---|
doc.toObject<T>() | Deserializa documento |
query.toObjects<T>() | Deserializa query a List |
query.toObjectsMap<T>() | Deserializa a Map<docId, T> |
docRef.set<T>(obj) | Guarda objeto serializado |
docRef.update<T>(obj) | Actualiza con objeto |
collection.add<T>(obj) | Add tipado |
batch.set<T>(ref, obj) | Set en batch |
tx.set<T>(ref, obj) | Set en transaction |
obj.toFirestoreMap() | Convierte @Serializable a Map |
| JavaScript | Interoperabilidad → Firebase JS SDK (npm) |
Surfaced from shared tags and platforms — no rankings paid for.