DEV Community

Cover image for NoSQL en Flutter
Alfredo Bautista 💙 #FlutterConf20
Alfredo Bautista 💙 #FlutterConf20

Posted on

NoSQL en Flutter

¡Buenas a todos! En este post veremos como usar una base de datos NoSQL en Flutter para guardar información de forma persistente.

SharedPreferences vs NoSQL databases

Muchos que hayáis estado trabajando/jugando con Flutter conoceréis que se recomienda el uso del paquete shared_Preferences para guardar información en formato clave-valor del usuario.

En mi caso, trabajando en un proyecto para utilizar Flutter en Mobile, web y desktop, encontré un problema para usarlo. En SO Linux no está soportado todavía por lo que debía encontrar otra solución. En ese momento encontré Sembast.

Sembast

Sembast es un paquete que nos permite trabajar con bases de datos NoSQL. Este paquete tiene bastantes versiones estables y un buen rating global sobre la estabilidad del mismo.

Para instalarlo únicamente deberemos añadirlo en nuestro pubspec.yaml

sembast: ^2.3.0

Planteamiento del problema

En mi aplicación necesitaba guardar el token de autentificación del usuario al hacer login y poder recuperarlo por cada petición que tuviera que hacer al backend.

Sembast en Web

En el día que escribo el artículo sembast tiene un paquete independiente para web pero que no voy a utilizar porque no permite la elección de la clave para guardar datos, debes recoger la clave al guardar el dato y usarla cuando quieras recuperarlo. Por esta razón voy a usar shared_preferences o sembast dependiendo de la plataforma donde corre.

Utilización

Este paquete nos provee de métodos para el acceso y guardado de datos NoSQL. En mi caso, he creado una clase TokenProvider estática para poder acceder al token y guardarlo sin tener que estar creando instancias del mismo y a la vez permitiendo diferenciar la plataforma donde corre y elegir que paquete usar. Empezamos indicando el fichero donde va a guardar la información.

import 'package:sembast/sembast.dart';
import 'package:sembast/sembast_io.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/foundation.dart' show kIsWeb;

class TokenProvicer{
  static final String dbPath = 'token.db';
  static final DatabaseFactory dbFactory = databaseFactoryIo;
}

Con esto tenemos indicado donde va a guardar la información y un objeto propio del paquete que nos permite trabajar con las bases de datos que le indiquemos.

Guardar el token

Para guardar el token simplemente he creado un método que recibe el token como String, abre una "conexión" a la base de datos, ya que es en local, y obtiene un store

Teniendo ya nuestra colección o store podemos proceder a guardar el token de forma asíncrona. El paquete nos proporciona un método record donde indicaremos su clave y con el método put indicamos su base de datos y lo que queremos guardar.

static __saveTokenMobilDesktop(String token) async {
    Database db = await dbFactory.openDatabase(dbPath);
    var store = StoreRef.main();

    await store.record('token').put(db, token);
  }

En el caso de correr en web y no poder utilizar este paquete

static __saveTokenWeb(String token) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    await prefs.setString('token', token);
  }

Y el método que expone y decide cómo guardar el token

static saveToken(String token) {
    kIsWeb ? __saveTokenWeb(token) : __saveTokenMobilDesktop(token);
  }

Recuperar el token

Teniendo la información guardada, únicamente debemos acceder a ella para poder leer el token y hacer las peticiones. En este caso, creamos otro método que no recibe parámetros y devuelve el token con el que vamos a hacer la petición.

static __loadTokenMobilDesktop() async {
    Database db = await dbFactory.openDatabase(dbPath);
    var store = StoreRef.main();

    return await store.record('token').get(db) as String;
  }

En el caso de usar shared_preferences.

  static __loadTokenWeb() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    return prefs.getString('token');
  }

Y el método que expone y decide.

static loadToken() {
    return kIsWeb ? __loadTokenWeb() : __loadTokenMobilDesktop();
  }

Uso en nuestra aplicación

Teniendo la clase creada, solo debemos referenciarla cuando vayamos a guardar el token, por ejemplo:

await loginProvider.login();
TokenProvicer.saveToken(loginProvider.token);

Y donde vayamos a hacer la petición.

this.token = await TokenProvicer.loadToken();
final response = await http.get(
      this.endPoint + username,
      headers: {'Authorization': 'Bearer $token'}
      );

Conclusión

Sembast es un paquete muy sencillo y estable para el manejo de bases de datos NoSQL aunque tenga la limitación de que en su parte web todavía no ofrece las mismas funcionalidades que en Mobile o Desktop.

Os animo a echarle un vistazo en su repo donde encontraréis muchos más ejemplos y características del paquete. También agradecer a la organización que ha creado y mantiene el paquete tekatrik

¡Un saludo y hasta la próxima!

Top comments (0)