
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.
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 |
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("io.github.romancanoniero:firebase-database")
implementation("io.github.romancanoniero:firebase-firestore")
implementation("io.github.romancanoniero:firebase-storage")
implementation("io.github.romancanoniero:firebase-functions")
implementation("io.github.romancanoniero:firebase-messaging")
implementation("io.github.romancanoniero:firebase-analytics")
}
}
}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
endLas 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 | Documentación completa de todas las funciones |
// 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) // iOS/JSval 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")
}
}
}val storage = FirebaseStorage.getInstance()
val imagesRef = storage.getReference("images")
// Subir archivo
val photoRef = imagesRef.child("photo.jpg")
val uploadTask = photoRef.putFile("/path/to/local/photo.jpg")
// Monitorear progreso
uploadTask.progressFlow.collect { progress ->
val percent = (100.0 * progress.bytesTransferred / progress.totalByteCount).toInt()
println("Subida: $percent%")
}
// Obtener URL de descarga
val downloadUrl = photoRef.getDownloadUrl()
println("URL: $downloadUrl")
// Descargar a archivo local
photoRef.getFile("/path/to/download/photo.jpg")
// Metadata
val metadata = photoRef.getMetadata()
println("Tamaño: ${metadata.sizeBytes} bytes")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("feature_enabled")
println("Mensaje: $welcomeMsg, Feature: $featureEnabled")
}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("https://api.example.com/data", "GET")
httpMetric.start()
// ... hacer request HTTP ...
httpMetric.setHttpResponseCode(200)
httpMetric.setResponsePayloadSize(1024)
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,
val email: String,
val age: Int = 0,
val active: Boolean = true
)
@Serializable
data class Post(
val title: String,
val content: String,
val authorId: String,
val likes: Int = 0
)import com.iyr.firebase.database.*
val database = FirebaseDatabase.getInstance()
// Deserializar un objeto
val user = database.getReference("users/user1").get().value<User>()
// Deserializar lista de objetos
val users = database.getReference("users").get().valueList<User>()
// Deserializar como Map de ID -> Objeto
val usersMap = database.getReference("users").get().valueMap<User>()
// Helpers para campos individuales
val name = snapshot.getString("name")
val age = snapshot.getLong("age")
val active = snapshot.getBoolean("active")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>()
// Deserializar como Map de docId -> Objeto
val usersMap = firestore.collection("users").get().toObjectsMap<User>()
// Observar con tipo
firestore.collection("users").snapshots.collect { query ->
val users = query.toObjects<User>()
}val user = User(name = "John", email = "john@example.com")
// Add tipado
val docRef = firestore.collection("users").add(user)
// Set tipado
firestore.document("users/user1").set(user)
// Update tipado
firestore.document("users/user1").update(User(name = "Jane"))
// Batch tipado
val batch = firestore.batch()
batch.set(userRef, user)
batch.update(postRef, postUpdate)
batch.commit()
// Transaction tipada
firestore.runTransaction { tx ->
val user = tx.get(userRef).toObject<User>()!!
val updated = user.copy(age = user.age + 1)
tx.set(userRef, updated)
updated
}| 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 |
# Android
./gradlew testDebugUnitTest
# iOS
./gradlew iosSimulatorArm64Test
# JavaScript
./gradlew jsNodeTestnpm install -g firebase-toolsfirebase emulators:start --only auth,database,firestore,storage,functions# Android
./gradlew connectedAndroidTest
# O el script incluido:
./run_integration_tests.shfirebase-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/ # App Check
└── firebase-inappmessaging/# In-App Messaging
| Plataforma | Tecnología |
|---|---|
| Android | Wrapper sobre Firebase Android SDK oficial |
| iOS | Kotlin/Native cinterop → Firebase iOS SDK (Objective-C) |
| JavaScript | Interoperabilidad → Firebase JS SDK (npm) |
Para desarrollo local:
./gradlew publishToMavenLocalLos 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 with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
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!
Librería Kotlin Multiplatform que replica fielmente la API del Firebase Android SDK para Android, iOS y JavaScript.
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 |
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("io.github.romancanoniero:firebase-database")
implementation("io.github.romancanoniero:firebase-firestore")
implementation("io.github.romancanoniero:firebase-storage")
implementation("io.github.romancanoniero:firebase-functions")
implementation("io.github.romancanoniero:firebase-messaging")
implementation("io.github.romancanoniero:firebase-analytics")
}
}
}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
endLas 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 | Documentación completa de todas las funciones |
// 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) // iOS/JSval 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")
}
}
}val storage = FirebaseStorage.getInstance()
val imagesRef = storage.getReference("images")
// Subir archivo
val photoRef = imagesRef.child("photo.jpg")
val uploadTask = photoRef.putFile("/path/to/local/photo.jpg")
// Monitorear progreso
uploadTask.progressFlow.collect { progress ->
val percent = (100.0 * progress.bytesTransferred / progress.totalByteCount).toInt()
println("Subida: $percent%")
}
// Obtener URL de descarga
val downloadUrl = photoRef.getDownloadUrl()
println("URL: $downloadUrl")
// Descargar a archivo local
photoRef.getFile("/path/to/download/photo.jpg")
// Metadata
val metadata = photoRef.getMetadata()
println("Tamaño: ${metadata.sizeBytes} bytes")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("feature_enabled")
println("Mensaje: $welcomeMsg, Feature: $featureEnabled")
}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("https://api.example.com/data", "GET")
httpMetric.start()
// ... hacer request HTTP ...
httpMetric.setHttpResponseCode(200)
httpMetric.setResponsePayloadSize(1024)
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,
val email: String,
val age: Int = 0,
val active: Boolean = true
)
@Serializable
data class Post(
val title: String,
val content: String,
val authorId: String,
val likes: Int = 0
)import com.iyr.firebase.database.*
val database = FirebaseDatabase.getInstance()
// Deserializar un objeto
val user = database.getReference("users/user1").get().value<User>()
// Deserializar lista de objetos
val users = database.getReference("users").get().valueList<User>()
// Deserializar como Map de ID -> Objeto
val usersMap = database.getReference("users").get().valueMap<User>()
// Helpers para campos individuales
val name = snapshot.getString("name")
val age = snapshot.getLong("age")
val active = snapshot.getBoolean("active")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>()
// Deserializar como Map de docId -> Objeto
val usersMap = firestore.collection("users").get().toObjectsMap<User>()
// Observar con tipo
firestore.collection("users").snapshots.collect { query ->
val users = query.toObjects<User>()
}val user = User(name = "John", email = "john@example.com")
// Add tipado
val docRef = firestore.collection("users").add(user)
// Set tipado
firestore.document("users/user1").set(user)
// Update tipado
firestore.document("users/user1").update(User(name = "Jane"))
// Batch tipado
val batch = firestore.batch()
batch.set(userRef, user)
batch.update(postRef, postUpdate)
batch.commit()
// Transaction tipada
firestore.runTransaction { tx ->
val user = tx.get(userRef).toObject<User>()!!
val updated = user.copy(age = user.age + 1)
tx.set(userRef, updated)
updated
}| 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 |
# Android
./gradlew testDebugUnitTest
# iOS
./gradlew iosSimulatorArm64Test
# JavaScript
./gradlew jsNodeTestnpm install -g firebase-toolsfirebase emulators:start --only auth,database,firestore,storage,functions# Android
./gradlew connectedAndroidTest
# O el script incluido:
./run_integration_tests.shfirebase-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/ # App Check
└── firebase-inappmessaging/# In-App Messaging
| Plataforma | Tecnología |
|---|---|
| Android | Wrapper sobre Firebase Android SDK oficial |
| iOS | Kotlin/Native cinterop → Firebase iOS SDK (Objective-C) |
| JavaScript | Interoperabilidad → Firebase JS SDK (npm) |
Para desarrollo local:
./gradlew publishToMavenLocalLos 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 with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
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!