El año pasado escribí sobre el uso de Couchbase Mobile en una aplicación móvil de Ionic Framework. Por aquel entonces usábamos Ionic Framework 1.0 y AngularJS 1.0. La tecnología ha cambiado con el paso de los meses y hemos pasado de lo que parecen frameworks antiguos a iteraciones mucho más modernas.

Con Angular 2 liberado y Ionic 2 cerca del lanzamiento estable, pensé que sería una gran idea revisar lo que había hecho anteriormente y explorar Couchbase Mobile en una aplicación Android y iOS Ionic 2.

Requisitos

Para hacer posible este proyecto vamos a necesitar algunas cosas instaladas y disponibles. Son las siguientes:

  • Node.js 4.0+
  • Marco Ionic 2.0
  • El SDK de Android o Xcode
  • Pasarela de sincronización Couchbase

Ionic Framework utiliza el Node Package Manager (NPM) que viene con Node.js para manejar todas las dependencias del proyecto. Para construir aplicaciones Android necesitaremos el SDK de Android instalado y para construir aplicaciones iOS necesitaremos un Mac con Xcode instalado. Por último, si queremos demostrar la sincronización, necesitaremos Couchbase Sync Gateway instalado y disponible.

Creación de un nuevo proyecto Ionic 2

Vamos a construir una aplicación de lista de tareas muy simple con Ionic 2, Angular 2 y TypeScript. Esta lista de tareas se sincronizará entre dispositivos y plataformas como se muestra en la imagen animada de abajo.

Ionic 2 with Couchbase

Esta es la misma aplicación que vimos en el tutorial de Ionic Framework 1.0 así como muchas otras tutoriales para móviles. Es la misma aplicación porque sirve de ejemplo muy útil.

Para simplificar las cosas, vamos a empezar con un proyecto nuevo. Desde el símbolo del sistema (Windows) o Terminal (Linux y Mac), ejecute lo siguiente:

Los comandos anteriores crearán un proyecto Ionic Framework 2.0 que utiliza Angular 2 y TypeScript. Aunque he elegido añadir las plataformas de compilación iOS y Android, no podremos compilar para iOS a menos que estemos usando un Mac con Xcode instalado.

Este proyecto depende de la Plugin PhoneGap de Couchbase para funcionar. No te alarmes. Aunque el nombre dice PhoneGap, en realidad no es más que un plugin de Apache Cordova, algo que es muy compatible con Ionic 2. Para instalar este plugin en el proyecto, ejecuta lo siguiente:

El plugin de Couchbase Lite para Apache Cordova funciona completamente con las APIs RESTful que están disponibles. Personalmente preferiría no trabajar con APIs en mi aplicación, así que construí una bonita envoltura JavaScript para convertir las APIs en una clase agradable. La envoltura,cordova-couchbasele permitirá utilizar métodos en lugar de preocuparse por las solicitudes HTTP a los puntos finales.

Para instalar cordova-couchbase en su proyecto, ejecute lo siguiente:

En este punto estamos listos para empezar a desarrollar la aplicación Ionic 2.

Gestión de Couchbase a través de un proveedor de Angular 2

Cuando se trabaja con bases de datos en una aplicación Angular 2, es una buena idea mantenerlas en un servicio, también conocido como proveedor. Esto nos permite no solo arrancar gran parte de la lógica de la base de datos en un único archivo, sino mantener nuestra capa de base de datos segregada del resto de nuestro código.

Usando la CLI de Ionic, ejecuta lo siguiente para generar una clase de proveedor:

Básicamente, el comando sólo crea un directorio y un archivo en src/providers/couchbase-provider.ts dentro del proyecto. Este proveedor debería tener un aspecto similar al siguiente:

Empecemos a pensar en cómo funcionará nuestro servicio Couchbase y en las piezas de código que lo integrarán para que sea un éxito.

Queremos que nuestro servicio de base de datos actúe como un singleton, lo que significa que queremos que se instancie una única clase de base de datos para toda la aplicación. Algo así como un servicio compartido. Podemos configurar esto a través de la constructor de nuestro proveedor:

Entonces, ¿qué está pasando en el código anterior hasta ahora? Primero creamos dos variables privadas. La booleana nos dirá si la base de datos ya ha sido instanciada. La Base de datos contendrá la base de datos abierta en ese momento.

Dentro de la constructor estamos haciendo nuestra comprobación lógica condicional. Debido a que el plugin de Apache Cordova utiliza código nativo necesitamos asegurarnos de que el dispositivo está listo. Esto se demuestra mediante el uso de Ionic's plataforma.lista método. Una vez que el dispositivo está listo podemos abrir una base de datos, incluso si no existe, y establecerla en nuestra variable privada.

La base de datos abierta puede recuperarse de nuestro proveedor utilizando el método anterior getDatabase método.

No hemos terminado con el CouchbaseProvider todavía. Probablemente deberíamos pensar en crear nuestras vistas MapReduce para futuras consultas y configurar nuestro escuchador de cambios. Todo esto ocurrirá dentro de la clase constructor después de establecer la base de datos abierta.

Por ejemplo, veamos lo siguiente:

En el código anterior hemos añadido un oyente que emitirá cambios a los que podremos suscribirnos en nuestro código Angular 2. Dentro de la variable constructor creamos una vista MapReduce llamada artículos con una lógica que emitirá pares clave-valor sólo si el documento contiene una propiedad llamada tipo que es igual a "list" y una propiedad llamada título que puede equivaler a cualquier cosa.

A continuación, la vista se añade a un documento de diseño de nuestra elección y se activa la escucha. Con el listener activado, cualquier cambio en la base de datos lo activará. Esto significa que si añadimos un documento, cambiamos un documento, o borramos un documento, el listener emitirá el cambio.

Se puede acceder a la escucha desde varias páginas de la aplicación llamando a la función getChangeListener función.

El proveedor está creado, pero actualmente no está siendo compartido a través de la aplicación. Para ello tenemos que importarlo en el Angular 2 @NgModule que se encuentra en el bloque src/app/app.module.ts archivo. Este archivo tendrá un aspecto similar al siguiente una vez terminado:

Observe que el proveedor se ha importado y añadido al proveedores array? Ahora podemos centrarnos en añadir lógica de aplicación.

Uso de Couchbase en la aplicación Ionic 2

Probablemente sea una buena idea abrir nuestra base de datos cuando se inicie la aplicación. Aunque podríamos hacerlo cuando se carga la primera página, no es necesario.

Abra el archivo src/app/app.component.ts e incluya el siguiente código TypeScript:

En el código anterior hemos importado el proveedor y lo hemos inyectado en el archivo constructor método. Esto se activará antes de que se cargue la primera página, se abra la base de datos, se cree la vista y se inicie el listener.

De aquí en adelante vamos a pasar nuestro tiempo en la primera y única página de la aplicación. Esto significa que vamos a pasar nuestro tiempo en el proyecto de src/pages/home/home.ts y src/pages/home/home.html archivos.

Abra el archivo src/pages/home/home.ts e incluya el siguiente código:

Vamos a desglosar lo que esto significa y añadir cada uno de los métodos uno por uno.

Puedes ver que estamos importando el archivo CouchbaseProvider junto con otros componentes. Exploraremos lo que significa cada uno a medida que vayamos llegando.

En artículos que es público contendrá todos nuestros todo-elementos que se presentarán en la interfaz de usuario, de ahí por qué es público. El constructor tiene muchas inyecciones para cada uno de los componentes que planeamos usar. También es donde inicializamos nuestro array público.

Nunca es aconsejable cargar datos en el constructor por lo que tenemos el método ionViewDidEnter método. En este método es donde se realiza la mayor parte del trabajo pesado:

Primero notarás el tiempo de espera. Estamos trabajando con muchos componentes asíncronos, específicamente el componente Couchbase. A menudo hay una condición de carrera donde la base de datos no estará lista a tiempo para cuando queramos usarla. Añadir un simple timeout de 100ms es más que suficiente para que la bola empiece a rodar. Hay otras maneras de hacer esto, pero el timeout es mi preferencia.

Cuando se carga la página queremos suscribirnos a nuestro listener creado en el proveedor. Cualquier dato emitido lo recorreremos en bucle. En este ejemplo en particular estamos ignorando los borrados y tratando los cambios y adiciones de la misma manera. En tu aplicación puede que quieras añadir una lógica más específica. Esencialmente estoy diciendo que siempre y cuando el cambio no fue un borrado, vamos a tomar la clave que se cambió y hacer una búsqueda en el documento. Si el documento es uno de nuestros documentos todo lo que queremos añadir a la matriz pública.

¿Qué está pasando con el zona ¿cosas? Los emisores pueden ponerse raros así que cuando recibimos un evento, queremos actualizar la zona de Angular 2. Puede que esto no te parezca necesario, pero si la interfaz de usuario no se actualiza con los cambios, no tener el zona cosas es por qué.

Una vez creado el receptor de cambios, queremos consultar la base de datos tal y como está ahora. Aquí es donde el actualizar entra en juego:

En actualizar consultará nuestra vista y añadirá cada uno de los elementos resultantes a nuestro array público. Sólo tenemos que consultar una vez porque los cambios que vienen en se añadirán automáticamente para nosotros como una conveniencia.

En añada es el método final de esta página Ionic 2:

Cuando se ejecute, aparecerá un mensaje. Cuando el usuario introduzca información en el prompt, se guardará como un documento dentro de Couchbase. El receptor de cambios recogerá este cambio local y lo añadirá a la lista.

La sencilla interfaz de usuario de esta aplicación, que se encuentra en la sección src/pages/home/home.html tiene el siguiente aspecto:

La interfaz de usuario tiene una barra de acción con un botón para mostrar el aviso. El contenido principal es una vista de lista en la que recorremos la matriz pública del archivo TypeScript.

Sincronización entre dispositivos y plataformas

Hasta ahora todo ha sido local a un dispositivo. Nada de lo que hemos añadido hasta ahora se ha encargado de la sincronización con Couchbase Sync Gateway u otros dispositivos. Sin embargo, añadir soporte de sincronización apenas requiere esfuerzo.

Abra el archivo src/providers/couchbase-provider.ts e incluya la siguiente línea después de abrir la base de datos:

Por supuesto, cambie el nombre de host y el nombre de la base de datos por los de su instancia remota de Sync Gateway. Ahora su aplicación se sincronizará continuamente. ¿No es increíble que una línea de código nos dio soporte de sincronización?

Si desea crear una instancia sencilla de Sync Gateway, aquí y ahora, cree lo siguiente sync-gateway-config.json file:

Cuando inicie Sync Gateway, diríjalo a ese archivo de configuración concreto. Actualice su sincronizar en la aplicación Ionic 2 para que coincida con el host y la base de datos.

Probar el proyecto terminado

Comprendo que esta guía sea un poco larga. Me he adelantado y he publicado una proyecto de muestra a GitHub que puedes ejecutar y revisar para complementar este tutorial.

Clona el proyecto ejecutando:

Con el proyecto descargado, necesitamos restaurar las dependencias del proyecto, plugins y plataformas. Ejecute lo siguiente para restaurar esas dependencias:

Ahora puedes proceder a ejecutar la aplicación en tu dispositivo o simulador. Eso sí, no olvides ejecutar Couchbase Sync Gateway y actualizar el sincronizar para reflejar el de su configuración remota.

Conclusión

Acabas de ver cómo crear una aplicación móvil híbrida multiplataforma iOS y Android con Iónico 2 que utiliza Couchbase Mobile. Este es un paso adelante y revisita de mi artículo anterior que demostró Ionic Framework 1.0 y Couchbase Mobile.

Autor

Publicado por Nic Raboy, Defensor del Desarrollador, Couchbase

Nic Raboy es un defensor de las tecnologías modernas de desarrollo web y móvil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y móvil más fácil de entender.

17 Comentarios

  1. Hola, equipo,

    Estoy tratando de ejecutar la aplicación y obtener alerta en la pantalla de inicio como "Couchbase Lite no está instalado"

    incluso he instalado los siguientes plugins.

    cordova plugin add cordova-plugin-whitelist

    cordova plugin add https://github.com/couchbaselabs/Couchbase-Lite-PhoneGap-Plugin.git

    1. ¿Estás intentando usar live-reload, ionic serve, o ionic view? Los plugins nativos no pueden ser emulados de esa manera, necesitan ser instalados en el dispositivo real o simulador desde el binario.

      ¿Puedes confirmar que no estás haciendo una de esas tres?

  2. Gracias por su rápida respuesta.

    Cuando ejecuto el comando "ionic cordova run android" Tengo el siguiente mensaje mientras se compila. Estoy dando el enlace de captura de pantalla también

    https://firebasestorage.googleapis.com/v0/b/tw-chatapp.appspot.com/o/Capture.PNG?alt=media&token=c3bfa5d6-8246-4196-9a89-7ef6941502a4

    [13:03:02] tslint: E:/E WORKS/CouchBase/src/pages/home/home.ts, line: 4
    Importación no utilizada: 'Couchbase'
    L3: import { CouchbaseProvider } from "../../providers/couchbase/couchbase";
    L4: import { Couchbase, Database } from "cordova-couchbase/core";
    [13:03:02] tslint: E:/E WORKS/CouchBase/src/pages/home/home.ts, line: 4
    Importación no utilizada: 'Base de datos'
    L3: import { CouchbaseProvider } from "../../providers/couchbase/couchbase";
    L4: import { Couchbase, Database } from "cordova-couchbase/core";

    Después de lanzar la aplicación tengo el siguiente error.
    https://firebasestorage.googleapis.com/v0/b/tw-chatapp.appspot.com/o/mobile.PNG?alt=media&token=e24e91f7-dce9-4c0c-a258-844001d72f0c

    Espero su respuesta.
    Gracias.

  3. Hola,

    Estoy intentando seguir este ejemplo, pero no puedo instalar el plugin Couchbase-Lite-PhoneGap.
    Cuando intento añadirlo utilizando
    "ionic cordova plugin add https://github.com/couchbaselabs/Couchbase-Lite-PhoneGap-Plugin.git
    Obtengo un error que dice que hay un problema de conexión o que la especificación del plugin es incorrecta. No es un problema de conexión, puedo añadir otros plugins desde github con el mismo comando.
    Cuando intento evitar el problema y descargo y descomprimo el plugin manualmente, y lo añado como plugin local con la ruta a la carpeta, obtengo un error de que falta un package.json válido.

    1. El comando es 'ionic plugin add' o 'cordova plugin add'. No existe el comando 'ionic cordova plugin add'.

      Lo mejor,

      1. En realidad el comando plugin ionic ha sido renombrado a plugin ionic cordova.
        "ionic cordova plugin add https://github.com/couchbaselabs/Couchbase-Lite-PhoneGap-Plugin.git" es el comando correcto para instalar el plugin, y no sé cómo solucionar el problema de Marburg.

      2. Por fin he conseguido configurarlo ahora.
        Pero cuando intento ionic serve -l la aplicación, me sale un this.couchbase.getDatabase(...) is undefined.

        1. No puedes servir este plugin porque es nativo. Debe ser compilado e instalado como si lo estuvieras haciendo de verdad.

          1. Por supuesto. Gracias por el comentario. Hace que sea más difícil de desarrollar y vivir-recargar, pero supongo que también se puede hacer en el modo de emulación.

          2. fin inesperado de la entrada JSON en
            Couchbase()).openDatabase("todolite").then(......

            [16:54:48] console.log: Ionic Native: evento deviceready disparado después de 2325 ms
            [16:54:48] error al abrir mensaje ws: {"category": "console", "type": "log", "data"
            ["DISPOSITIVO LISTO DESPUÉS",2152, "ms"]}
            [16:54:48] console.error: ERROR
            [objeto Objeto]
            [16:54:48] console.error: ERROR
            [objeto Objeto]

  4. Hola Nic Raboy,

    Soy principiante en Couchbase y quiero desarrollar aplicación móvil híbrida multiusuario en ionic con sincronización de datos.
    Ya desarrollo aplicación android (nativo) con MySQL como back-end y dispuesto a convertir esa base de datos MySQL con Couchbase para soporte offline. Entonces, ¿qué cosas debo seguir y cómo convertir la base de datos MySQL en Couchbase.
    Gracias de antemano

  5. captura de pantalla del error con todos los detalles.
    He comentado lo de conectar con el sync_gateway, por lo que es ya al configurar la base de datos local, cuando se produce el error json.

    https://drive.google.com/file/d/0B0KRHtKNSw4xUXdfMWhEcU16Nms/view?usp=sharing

    1. Está dentro del wrapper cordova-couchbase. Ahora he añadido esos archivos al proyecto y los llamo localmente.
      Hasta ahora he podido rastrearlo hasta el método makeRequest de database.ts.

      1. Ok, fui tan lejos como pude.
        tirando del wrapper cordova-couchbase dentro del proyecto, y arreglando el bug #3, como hizo Murilo Perrone, arregló el error json parse, pero no hace que la demo funcione.
        He añadido un poco de información de depuración a la console.log, por lo que el evento deviceready realmente se dispara, después de 13 segundos,
        el couchbase.openDatabase() llama al database.getDatabase(), que llama al método makeRequest con método GET y url http://c3c19c87-dcc1-4b6d-a3db-fc7be65a427f:7adfa00d-0fd7-44ea-95b9-3cbe7f0609dd@localhost:5984/councilapp

        Todo parece ir bien. Simplemente no parece devolver nada, porque más adelante, this.couchbase.getDatabase() permanece indefinido,
        no puede leer queryView de undefined,
        no puede leer getDocument de undefined.

        Así que he intentado durante 3 días, con el conocimiento limitado que tengo, pero simplemente no puedo hacer que funcione más. Este es probablemente el punto en el que me daré por vencido.

        17:39:22] console.log: Angular se está ejecutando en el modo de desarrollo. Llama a enableProdMode() para habilitar el modo de producción.
        modo.
        17:39:23] console.log: deviceready no se ha disparado después de 5 segundos.
        17:39:23] console.warn: Ionic Native: deviceready no se disparó en 5000ms. Esto puede ocurrir cuando los plugins están en un
        estado incoherente. Prueba a eliminar plugins de plugins/ y reinstalarlos.
        17:39:23] console.warn: Nativo: deviceready no se disparó en 5000ms. Esto puede ocurrir cuando los plugins están en un
        estado incoherente. Prueba a eliminar plugins de plugins/ y reinstalarlos.
        17:39:23] console.log: Ionic Native: evento deviceready disparado tras 12030 ms.
        17:39:23] console.log: DISPOSITIVO LISTO DESPUÉS DE 11374 ms
        17:39:23] console.log: método: GET, url:
        http://c3c19c87-dcc1-4b6d-a3db-fc7be65a427f:7adfa00d-0fd7-44ea-95b9-3cbe7f0609dd@localhost:5984/councilapp
        17:39:26] console.error: ERROR [objeto Objeto]

  6. La razón por la que no me funciona es en el wrapper cordova-couchbase.
    En la línea18 del couchbase.ts de ese proyecto, se hace una promesa con database.getDatabase().then(result......)
    en la línea 21, capturas los posibles errores, pero asumes que error.status existe.
    En mi caso, el propio error es nulo, de ahí que todo lo demás también falle.

    1. Tengo una versión funcionando.
      Ahora noto que el plugin no funciona bien con -livereload.
      La aplicación funciona cuando la ejecuto en un emulador sin livereload.
      El plugin se bloquea en la primera acción realizada en el plugin cuando lo ejecuto en un emulatir con livereload.

  7. DISPOSITIVO LISTO DESPUÉS DE 590 ms
    Couchbase Lite no está instalado.
    EXCEPCIÓN: No se puede leer la propiedad 'queryView' de undefined
    STACKTRACE ORIGINAL:
    TypeError: No se puede leer la propiedad 'queryView' de undefined
    at t.refresh (file:///android_asset/www/build/main.js:10:22154)
    at file:///android_asset/www/build/main.js:10:22067
    at t.invokeTask (file:///android_asset/www/build/polyfills.js:3:14051)
    at Object.onInvokeTask (file:///android_asset/www/build/main.js:3:29640)
    at t.invokeTask (file:///android_asset/www/build/polyfills.js:3:13987)
    at e.runTask (file:///android_asset/www/build/polyfills.js:3:11411)
    at invoke (file:///android_asset/www/build/polyfills.js:3:15164)

    Vea esta captura de pantalla
    http://prntscr.com/gy09lz

Dejar una respuesta