Persistir data usando HiveDB en Flutter

- 👤 Andrés Cruz

🇺🇸 In english

Si estás buscando una forma rápida, eficiente y sin complicaciones de guardar datos localmente en Flutter, HiveDB es probablemente una de las mejores opciones. En mi caso, lo uso cuando necesito persistir datos simples o listas pequeñas sin tener que montar una base de datos compleja como viene siendo la de SQFlite con Flutter que conocimos anteriormente. HiveDB tiene una API muy directa basada en clave–valor, y eso lo hace ideal para quienes queremos “guardar y recuperar” sin fricción.

HiveDB junto con los sharedpreferences que vimos en una entrada anterior, es uno de las formas populares que tenemos en persistir datos en nuestra aplicación en Flutter; HiveDB tiene una API sencilla para almacenar y obtener los datos como vamos a ver en esta entrada.

Qué es HiveDB y cuándo usarlo en Flutter

HiveDB es una base de datos NoSQL local, optimizada para Flutter y escrita en Dart. Aunque a veces se le compara con SharedPreferences, Hive puede almacenar prácticamente cualquier tipo de dato: enteros, cadenas, mapas y hasta modelos tipados (si usas adapters).

Por qué es popular frente a SharedPreferences

Cuando recién empecé con Hive, lo que más me atrajo fue lo simple que resultaba almacenar mapas completos. Con SharedPreferences todo termina reducido a strings y tipos básicos, así que Hive es perfecto cuando necesitas guardar estructuras un poco más complejas sin convertir nada.

Ventajas y limitaciones reales (incluyendo Isar)

Ventajas:

  • Muy rápido (usa almacenamiento binario).
  • Funciona offline.
  • Apto para listas pequeñas o medianas.
  • No requiere SQL.
  • Ideal para configuraciones, listas personalizadas, favoritos, etc.

Limitaciones:

  • Carga toda la box en memoria, así que no lo uses para miles de registros.
  • Para modelos complejos necesitas generar adapters.
  • La comunidad comenta que Isar puede ser mejor para grandes volúmenes o consultas más avanzadas.
  • Aun así, cuando la lógica es simple, Hive sigue siendo una opción excelente y en mi experiencia nunca me dio problemas salvo cuando olvidé inicializarlo (y créeme, ese error aparece bastante).

Instalación e inicialización de HiveDB en Flutter

Comencemos agregando la dependencia en nuestro archivo:

pubspec.yaml

dependencies: 
    hive:
    hive_flutter:

Ahora, falta inicializarlo, para eso, agregamos la siguiente línea de código en el main.dart:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Hive.initFlutter();
  runApp(ProviderScope(child: MyApp()));
}

Es el código más o menos típico que empleamos al momento de inicializar procesos asíncronas a nivel de toda la aplicación y con Hive.initFlutter() inicializamos Hive.

Como vamos a ver en el siguiente apartado, Hive trabaja con el esquema clave valor, en donde el valor puede ser una primitiva o un mapa.

Crear estructura básica en Hive

Al igual que ocurre con los sharedpreferences, debemos de crear una estructura con la cual podemos gestionar los datos de manera persistentes; en Hive, donde almacenamos los datos, se conocen como "boxes" los cuales tienen un nombre para hacer el seguimiento y con esto, obtener y establecer datos:

class MyListService {
  static MyListService? _instance;
  final String boxName = 'myList';
  MyListService._();
  static MyListService get instance {
    if (_instance == null) {
      _instance = WatchlistService._();
    }
    return _instance!;
  }
}

Apertura y gestión de boxes

Con la estructura anterior, creamos una instancia única la cual accedemos para gestionar nuestros datos; el siguiente paso consiste en definir los métodos para almacenar los datos; este primer método permite crear un nuevo registro para un item o actualizar si el ID existe:

Future<void> addToMyList(int id, Map<String, 
    dynamic> item) async {
  final box = await Hive.openBox<Map<String, 
      dynamic>>(boxName);
  if (box.get(id) == null) {
    box.put(id, item);
  }
}

El código anterior permite abrir la box, para que podamos administrar la misma, en este caso, hacer el pub del item mediante el ID.

Para remover un item desde hive, tenemos:

Future<void> removeFromMyList(int id) async {
  final box = await Hive.openBox(boxName);
  box.delete(id);
}

También, podemos crear un método que verifica si un item esta en la lista mediante el ID:

Future<bool> isInMyList(int id) async {
  final box = await Hive.openBox(boxName);
  return box.containsKey(id);
}

Trabajo con clave–valor y mapas

Hive funciona genial con mapas. Yo suelo guardar mis elementos así:

Future<void> addToMyList(int id, Map<String, dynamic> item) async {
 final box = await Hive.openBox<Map<String, dynamic>>(boxName);
 if (box.get(id) == null) {
   box.put(id, item);
 }
}

Finalmente, tenemos un método para obtener todos los datos de la lista:

Future<Iterable<Map<String, dynamic>>> geMylist() async {
  Final box = await Hive.openBox<Map<String, 
      dynamic>>(boxName);
  return box.values;
}

Casi siempre inicializo HiveDB en el main() al arrancar la app:

void main() async {
 WidgetsFlutterBinding.ensureInitialized();
 await Hive.initFlutter();
 runApp(MyApp());
}

Opcional: Crear la estructura base: boxes y servicio para manejar datos

También, puedes emplear una estructura tipo Singleton para centralizar todo el acceso:

Mi estructura Singleton para acceder a los datos

class MyListService {
 static MyListService? _instance;
 final String boxName = 'myList';
 MyListService._();
 static MyListService get instance {
   _instance ??= MyListService._();
   return _instance!;
 }
}

CRUD completo con HiveDB (con ejemplos prácticos)

Crear o actualizar un item

Future<void> addToMyList(int id, Map<String, dynamic> item) async {
 final box = await Hive.openBox<Map<String, dynamic>>(boxName);
 box.put(id, item); // put sirve para crear o sobrescribir
}

Leer datos individuales y listas

Future<Map<String, dynamic>?> getItem(int id) async {
 final box = await Hive.openBox<Map<String, dynamic>>(boxName);
 return box.get(id);
}

Obtener todos los valores:

Future<Iterable<Map<String, dynamic>>> getMyList() async {
 final box = await Hive.openBox<Map<String, dynamic>>(boxName);
 return box.values;
}

Verificar si un elemento existe

Future<bool> isInMyList(int id) async {
 final box = await Hive.openBox(boxName);
 return box.containsKey(id);
}

Eliminar items o limpiar toda la box

Future<void> removeFromMyList(int id) async {
 final box = await Hive.openBox(boxName);
 box.delete(id);
}

Buenas prácticas usando HiveDB en apps reales

Cuándo usar mapas y cuándo usar modelos tipados

  • Mapas: cuando quieres simplicidad y velocidad (yo lo uso así para listas pequeñas).
    • Modelos tipados + adapters: si quieres validaciones o estructuras más sólidas.
    • Evitar problemas comunes al abrir boxes.
  • Siempre abre las boxes una sola vez por servicio.
  • Abrir y cerrar varias veces dentro del árbol de widgets puede afectar el rendimiento.
  • Gestión eficiente de servicios y acceso a datos
  • La estructura Singleton que uso permite:
    • mantener un único acceso centralizado
    • reducir la repetición de código
    • evitar errores de inicialización

Errores comunes de HiveDB y cómo los soluciono

  1. “You need to initialize Hive”
    1. Solución: agrega await Hive.initFlutter() antes de runApp.
  2. “Box not found / Did you forget to openBox()?”
    1. Solución: abre la box antes de usarla:
    2. await Hive.openBox('myList');
  3. MissingPluginException en dispositivos reales
    1. Solución: reinstala la app.
  4. Me ha pasado varias veces en modo debug.

HiveDB vs otras alternativas (SharedPreferences e Isar)

Cuándo elegir cada opción

  • SharedPreferences
    • Configuraciones simples
    • Flags booleanos
    • Datos muy pequeños
  • HiveDB
    • Listas, mapas y estructuras simples
    • Favoritos, listas de IDs, configuraciones dinámicas
    • Apps pequeñas o medianas
  • Isar
    • Mucho volumen de datos
    • Consultas avanzadas
    • Relaciones complejas

Conclusión

HiveDB sigue siendo una forma rápida, limpia y eficiente de guardar datos locales en Flutter. En mi experiencia, cuando sólo necesito persistir listas pequeñas o mapas, Hive me da exactamente lo que busco: velocidad y simplicidad sin complicar la arquitectura. Y si algún día necesitas más potencia, siempre puedes dar el salto a Isar o a una base SQL.

Preguntas frecuentes sobre HiveDB en Flutter

  • ¿Hive es seguro para datos sensibles?
    • Sí, si usas cifrado con HiveAesCipher.
  • ¿Puedo guardar listas o modelos complejos?
    • Sí, listas funcionan sin problema; para modelos debes usar adapters.
  • ¿Hive seguirá siendo compatible con Isar?
    • Hive v4 usará backend basado en Isar; la interoperabilidad será cada vez mayor.

Estos son solamente algunos métodos que puedes crear, pero, existen otros que puedes definir a gusto según tus necesidades.

Una de las operaciones más interesantes que podemos hacer es montar una pasarela de pagos con Stripe y Flutter.

Acepto recibir anuncios de interes sobre este Blog.

HiveDB junto con los sharedpreferences uno de las formas que tenemos en persistir datos en nuestra aplicación en Flutter; HiveDB tiene una API sencilla para almacenar y obtener los datos como vamos a ver en esta entrada.

| 👤 Andrés Cruz

🇺🇸 In english