El almacenamiento de datos es una de las tareas clave de una aplicación móvil, que afecta al rendimiento, la seguridad y la experiencia del usuario. En este artículo analizaremos SQLite, Room, Core Data, Realm, Firebase Firestore, SharedPreferences, DataStore, Keystore y Keychain, así como los formatos de serialización (JSON, Protobuf) y las bibliotecas (Gson, Moshi, kotlinx.serialization). Esta guía ayudará a los desarrolladores principiantes a elegir la solución de almacenamiento de datos adecuada. Más información en la guía oficial de Android sobre almacenamiento de datos.
Puntos clave
Para almacenar datos estructurados con relaciones entre entidades se utilizan bases de datos relacionales.
SQLite es una base de datos relacional embebida que funciona en cualquier plataforma móvil. No requiere un servidor independiente y los datos se almacenan en un solo archivo. SQLite es la base de Room (Android) y opcionalmente de Core Data (iOS). Bibliotecas: android.database.sqlite (Android), FMDB/Core Data (iOS), sqflite (Flutter).
Room es la biblioteca oficial de Android Architecture Components para trabajar con SQLite. Proporciona una capa ORM: Entity (tabla), DAO (consultas), Database (punto de entrada). Room verifica las consultas SQL en tiempo de compilación, admite corrutinas y Flow, y migra automáticamente el esquema.
@Entity data class User( @PrimaryKey val id: Int, val name: String, val email: String ) @Dao interface UserDao { @Query("SELECT * FROM user WHERE id = :id") suspend fun getUser(id: Int): User? }
Core Data es el framework de Apple para gestionar un grafo de objetos. No es una base de datos pura, sino una capa de persistencia sobre SQLite, XML o almacenamiento binario. Core Data gestiona objetos (NSManagedObject), relaciones, versionado de esquemas, deshacer/rehacer y trabajo con múltiples hilos a través de NSManagedObjectContext.
Realm es una alternativa a SQLite, diseñada como una base de datos móvil de alto rendimiento. Realm es más rápida que SQLite en lectura y escritura, admite notificaciones reactivas (Live Objects), cifrado en tiempo real y multiplataforma (Android, iOS, Flutter, React Native). Desventajas: mayor tamaño de APK/IPA y mayor consumo de memoria.
Para almacenar pequeñas cantidades de datos (configuración, tokens, caché) se utilizan almacenes simples de pares clave-valor.
SharedPreferences es un almacén heredado de pares clave-valor en Android. Desventajas: acceso síncrono (bloquea la UI al leer), falta de tipado, riesgo de ANR al cargar archivos grandes. NO recomendado para proyectos nuevos.
DataStore es el reemplazo moderno de SharedPreferences de Google. Funciona de forma asíncrona mediante Kotlin Coroutines y Flow, admite Preferences DataStore (clave-valor) y Proto DataStore (datos tipificados mediante Protobuf). DataStore es seguro para el hilo de UI y admite transacciones.
UserDefaults es el almacenamiento estándar para pequeñas configuraciones en iOS. Admite tipos primitivos, cadenas, fechas y Data. UserDefaults es síncrono, por lo que no es adecuado para grandes volúmenes de datos. El registro de valores mediante register(defaults:) establece los valores por defecto.
Para almacenar datos en aplicaciones que requieren sincronización entre dispositivos se utilizan bases de datos en la nube de Firebase.
Firebase Firestore es una base de datos documental NoSQL con suscripciones en tiempo real, escalado automático, consultas potentes y modo offline integrado. Los datos se organizan en colecciones y documentos (estructuras similares a JSON). Firestore admite transacciones y operaciones por lotes. Ideal para chats, feeds y aplicaciones sociales.
Firebase Realtime Database es una base de datos NoSQL más antigua de Firebase que almacena datos como un único árbol JSON. Más simple que Firestore, pero menos flexible en consultas y escalado. Recomendada para aplicaciones simples en tiempo real (estado en línea, chats simples).
| Característica | Cloud Firestore | Firebase Realtime DB |
|---|---|---|
| Modelo de datos | Colecciones → Documentos | Árbol JSON |
| Consultas | Complejas (filtrado, ordenación, límites) | Simples (por clave) |
| Escalado | Automático | Fragmentación manual |
| Modo offline | Sí (caché persistente) | Sí |
| Precio | Por operaciones de lectura/escritura | Por tráfico + almacenamiento |
El almacenamiento de tokens, contraseñas y claves de cifrado requiere almacenes protegidos especiales.
Android Keystore es un almacén de sistema para claves criptográficas. Las claves se almacenan en un entorno hardware (TEE — Trusted Execution Environment), inaccesible para aplicaciones y el sistema operativo. Admite generación de claves, cifrado y firma. Con Android 9+ incluye StrongBox Keymaster (chip dedicado).
Keychain Services es un almacén seguro de iOS para contraseñas, claves y certificados. Los datos se cifran utilizando el Secure Enclave hardware. Keychain admite niveles de accesibilidad: Always, WhenUnlocked, WhenUnlockedThisDeviceOnly, AfterFirstUnlock.
EncryptedSharedPreferences es un envoltorio sobre SharedPreferences con cifrado de claves y valores mediante AES256-GCM y HKDF. Implementado en la biblioteca AndroidX Security. Recomendado para almacenar tokens y configuraciones confidenciales.
En IT Sectr utilizamos Android Keystore + EncryptedSharedPreferences para almacenar tokens de actualización y claves biométricas. En iOS utilizamos Keychain con el nivel kSecAttrAccessibleWhenUnlockedThisDeviceOnly para máxima seguridad.
Para el almacenamiento de archivos (imágenes, vídeos, documentos), las plataformas móviles ofrecen varios tipos de almacenamiento.
Android distingue entre Internal Storage (/data/data/paquete/ — almacenamiento privado) y External Storage (tarjeta SD o partición emulada). Cache Directory es un almacenamiento temporal que el sistema puede limpiar. Scoped Storage (Android 10+) restringe el acceso a External Storage — las aplicaciones solo ven sus propios archivos o archivos a través de MediaStore/SAF.
iOS proporciona Documents Directory (copia de seguridad de iCloud, datos persistentes), Library/Caches (archivos temporales, no se respaldan) y Tmp Directory (temporales, pueden limpiarse). Use NSFileManager para trabajar con el sistema de archivos. iOS 11+ admite File Provider para archivos en la nube.
La serialización convierte objetos en un formato para su transmisión o almacenamiento. La deserialización es el proceso inverso.
JSON (JavaScript Object Notation) es el formato más popular: legible, flexible, compatible con todas las plataformas. XML es más estricto, se utiliza en sistemas heredados. Protobuf (Protocol Buffers) es un formato binario de Google: de 3 a 10 veces más compacto que JSON, se analiza más rápido y tiene un esquema estricto. Se utiliza para sistemas de alta carga y microservicios.
JSONSerialization es la API integrada para trabajar con JSON. Codable (Encodable/Decodable) es un protocolo moderno de Swift para la serialización automática a JSON, Property List y otros formatos.
struct User: Codable { let id: Int let name: String let email: String } let user = User(id: 1, name: "Alice", email: "alice@example.com") let encoder = JSONEncoder() let jsonData = try encoder.encode(user)
Para Flutter y React Native existen bibliotecas de almacenamiento eficientes propias.
Hive es un almacén clave-valor ligero y rápido para Flutter. No requiere código nativo (Dart puro), admite tipificación mediante TypeAdapter y funciona en isolates. Ideal para caché, configuraciones y pequeños volúmenes de datos.
ObjectBox es una base de datos embebida de alto rendimiento para Flutter, Android e iOS. Es 10 veces más rápida que SQLite y utiliza una estructura de archivos plana para una sobrecarga mínima. Admite relaciones, consultas y suscripciones reactivas (ObjectBox Dart).
Drift es una biblioteca SQLite reactiva para Flutter y Dart. Proporciona consultas tipificadas, migraciones, funciones DAO y soporte para Stream (actualizaciones reactivas). Drift es la opción principal para proyectos Flutter que requieren SQLite.
Preguntas frecuentes
La elección depende de la plataforma: Room (Android) es la biblioteca oficial basada en SQLite con verificación de consultas en tiempo de compilación. Core Data (iOS) es el framework de Apple con un grafo de objetos. Para proyectos multiplataforma, Realm o SQLite mediante ORM son adecuados.
SharedPreferences es una implementación antigua con acceso síncrono y riesgo de ANR. DataStore (Jetpack) es un reemplazo moderno basado en Kotlin Coroutines y Flow, que admite asincronía, tipificación y protección contra errores.
Android: EncryptedSharedPreferences o Android Keystore. iOS: Keychain Services con nivel de accesibilidad WhenUnlockedThisDeviceOnly. Para datos críticos, use Secure Enclave (iOS) y Keystore hardware (Android) con biometría.
Cloud Firestore es una base de datos NoSQL de Firebase con sincronización en tiempo real, modo offline y escalado automático. Es adecuada para chats, feeds de noticias y proyectos que necesitan sincronización entre dispositivos.
Flutter: Hive (clave-valor rápido), Floor (ORM SQLite), Drift (Moor, SQLite reactivo), ObjectBox (BD embebida de alto rendimiento). React Native: Realm, WatermelonDB (carga diferida) y AsyncStorage (análogo a SharedPreferences).
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.