Ionic Framework sigue siendo uno de los líderes en el desarrollo de aplicaciones móviles híbridas. Permite crear aplicaciones para Android e iOS.
utilizando sólo HTML, JavaScript y CSS.
Anteriormente escribí sobre cómo utilizar Couchbase en
una aplicación móvil Android e iOS con Ionic Frameworkpero hacía uso de Couchbase
Lite como su base de datos NoSQL integrada. En esta ocasión vamos a ver cómo sustituir Couchbase Lite por PouchDB. ¿Deberías usar una
método sobre el otro? No, al final todo se reduce a preferencias.
Si todavía no ha visto mi post sobre PouchDB
y AngularJS con CouchbaseSi estás interesado, te animo a que le eches un vistazo, ya que este tutorial utilizará muchos de los mismos conceptos y código.
Qué necesitaremos
Hay algunos requisitos para la aplicación que vamos a construir. Veremos cómo obtenerlos a lo largo del camino, pero aquí hay un
sabor para que sepas en qué te estás metiendo.
- Pasarela de sincronización Couchbase
- PouchDB 4
- Marco iónico 1
Obtención de la puerta de enlace Couchbase Sync
Este proyecto requerirá Couchbase Sync Gateway para tener éxito. Si no estás familiarizado, el Couchbase Sync Gateway es un
que se encarga de procesar los datos entre la aplicación local (tu aplicación Ionic Framework) y el servidor Couchbase. Nosotros
no utilizaremos Couchbase Server en este ejemplo, por lo que Sync Gateway actuará como nuestra solución de almacenamiento en memoria en la nube.
La puerta de enlace de sincronización de Couchbase se encuentra en la dirección Sección de descargas de Couchbase.
Creación de nuestro proyecto Ionic Framework
Antes de seguir adelante es bueno tener en cuenta que si usted no está usando un Mac, no se puede añadir y construir para la plataforma iOS. Windows, Mac,
y Linux pueden construir para Android, pero sólo Mac puede construir para iOS.
Desde el símbolo del sistema (Windows) o Terminal (Mac y Linux), ejecute el siguiente comando para crear un nuevo proyecto de Ionic Framework:
1 2 3 4 5 6 |
iónico iniciar BolsaProyecto en blanco cd BolsaProyecto iónico plataforma añada android iónico plataforma añada ios |
Nuestro proyecto de plantilla en blanco ya está listo para trabajar con él.
Incluir las dependencias
Si aún no lo has hecho, descargar PouchDB 4 y tome nota de la min.js archivo como
que utilizaremos en el proyecto. Copia el
PouchDB min.js en el archivo www/js directorio.
Con el archivo en su sitio, abra el archivo www/index.html e incluya lo siguiente:
1 2 3 |
Esta línea de script debe aparecer encima de app.js y la información de la versión debe coincidir con la de su actual
en lugar de la versión que he incluido aquí.
Modificación del fichero índice
Antes de pasar al código de AngularJS, tenemos que hacer una revisión final del proyecto www/index.html archivo. Ábralo y
sustituye las etiquetas por lo siguiente:
1 2 3 4 5 6 7 8 |
Dado que estamos utilizando el UI-Router de AngularJS que se incluye con Ionic Framework, sólo necesitamos una aplicación básica www/index.html archivo.
Creación de nuestro servicio PouchDB AngularJS
Antes de empezar a utilizar PouchDB, tenemos que hacer una envoltura para que se ajuste bien con AngularJS y Ionic Framework. Fuera de la caja PouchDB
es una biblioteca JavaScript de vainilla, por lo que no es necesariamente la más fácil de usar cuando se trata de AngularJS.
Dentro de la sección www/js/app.js incluya el siguiente código de servicio:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
.servicio("$pouchDB", ["$rootScope", "$q", función($rootScope, $q) { var base de datos; var changeListener; este.setDatabase = función(databaseName) { base de datos = nuevo PouchDB(databaseName); } este.startListening = función() { changeListener = base de datos.cambia({ en directo: verdadero, incluir_docs: verdadero }).en("cambio", función(cambiar) { si(!cambiar.suprimido) { $rootScope.$difusión("$pouchDB:cambio", cambiar); } si no { $rootScope.$difusión("$pouchDB:eliminar", cambiar); } }); } este.stopListening = función() { changeListener.cancelar(); } este.sincronizar = función(remoteDatabase) { base de datos.sincronizar(remoteDatabase, {en directo: verdadero, reintentar: verdadero}); } este.guardar = función(jsonDocument) { var aplazado = $q.aplazar(); si(!jsonDocument._id) { base de datos.Correo electrónico:(jsonDocument).entonces(función(respuesta) { aplazado.resolver(respuesta); }).captura(función(error) { aplazado.rechace(error); }); } si no { base de datos.poner(jsonDocument).entonces(función(respuesta) { aplazado.resolver(respuesta); }).captura(función(error) { aplazado.rechace(error); }); } devolver aplazado.promesa; } este.borrar = función(documentId, revisióndeldocumento) { devolver base de datos.eliminar(documentId, revisióndeldocumento); } este.consiga = función(documentId) { devolver base de datos.consiga(documentId); } este.destruir = función() { base de datos.destruir(); } }]) |
Puede que ese código te resulte familiar. Pues bien, es el código exacto que utilicé en
el ejemplo anterior de PouchDB para AngularJS.
Ahora podemos utilizar fácilmente PouchDB en nuestro proyecto.
Crear una base de datos local e iniciar la sincronización
El objetivo aquí es crear una base de datos local cuando nuestra aplicación se inicia (si no existe ya) y luego comenzar a sincronizar con el
Couchbase Sync Gateway. Esto se puede lograr en el AngularJS ejecutar() función de nuestro www/js/app.js
file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
.ejecute(función($ionicPlatform, $pouchDB) { $ionicPlatform.listo(función() { si(ventana.Córdoba && ventana.Córdoba.plugins.Teclado) { Córdoba.plugins.Teclado.hideKeyboardAccessoryBar(verdadero); } si(ventana.Barra de estado) { Barra de estado.styleDefault(); } }); $pouchDB.setDatabase("nraboy-test"); si(iónico.Plataforma.isAndroid()) { $pouchDB.sincronizar("http://192.168.57.1:4984/test-database"); } si no { $pouchDB.sincronizar("http://localhost:4984/test-database"); } }) |
Las direcciones IP que he utilizado pueden variar para usted en términos de simuladores, pero para la producción es probable que coincida tanto para iOS y
Android.
Diseño de un controlador para sus vistas
Todavía no hemos creado nuestras vistas, pero vamos a seguir adelante y crear la lógica del controlador para ellos. Abre el archivo
www/js/app.js e incluya el siguiente controlador:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.controlador("MainController", función($alcance, $rootScope, $estado, $stateParams, $ionicHistory, $pouchDB) { $alcance.artículos = {}; $alcance.guardar = función(nombre, apellido, correo electrónico) { } $alcance.borrar = función(id, rev) { } $alcance.volver = función() { } }) |
En este momento tenemos un controlador básico. Sabemos que vamos a guardar y eliminar elementos, por lo que hemos definido una función para ello
tareas. También tenemos una función llamada atrás() que hará aparecer un elemento (retroceder) en la pila del historial.
Vayamos de abajo arriba y empecemos por el atrás() función. Debe contener el siguiente código:
1 2 3 4 5 |
$alcance.volver = función() { $ionicHistory.goBack(); } |
Cuando se trata de eliminar elementos de la base de datos, tendremos que proporcionar un identificador de documento concreto para eliminar, así como la revisión concreta
que deseamos eliminar. Todo esto se pasará desde las vistas, pero la lógica será la siguiente:
1 2 3 4 5 |
$alcance.borrar = función(id, rev) { $pouchDB.borrar(id, rev); } |
En suprimir(id, rev) hace una llamada al servicio PouchDB que hemos creado.
Esto nos deja con la guardar() función. Basándonos en la simplicidad de nuestra aplicación sólo guardaremos tres datos
pero puede cambiarse fácilmente si es necesario. Dentro de su controlador, haga que el guardar() así:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$alcance.guardar = función(nombre, apellido, correo electrónico) { var jsonDocument = { "nombre": nombre, "apellido": apellido, "email": correo electrónico }; si($stateParams.documentId) { jsonDocument["_id"] = $stateParams.documentId; jsonDocument["_rev"] = $stateParams.revisióndeldocumento; } $pouchDB.guardar(jsonDocument).entonces(función(respuesta) { $estado.ir("lista"); }, función(error) { consola.registro("ERROR -> " + error); }); } |
Esta función hace dos cosas. Preparará una inserción o preparará una actualización en caso de que un id de documento y una revisión de documento
estar disponible.
Pero aún no hemos terminado. Aunque hemos terminado todas nuestras funciones, todavía tenemos que manejar la escucha de
cambios. Cuando llamamos a $pouchDB.startListening(); en nuestro controlador, nuestro servicio PouchDB empezará a hacer uso de la función
AngularJS $ransmisión. Mientras está emitiendo podemos escuchar esas emisiones usando algo como:
1 2 3 4 5 6 7 8 9 10 11 |
$rootScope.$en("$pouchDB:cambio", función(evento, datos) { $alcance.artículos[datos.doc._id] = datos.doc; $alcance.$aplicar(); }); $rootScope.$en("$pouchDB:eliminar", función(evento, datos) { borrar $alcance.artículos[datos.doc._id]; $alcance.$aplicar(); }); |
La lógica de nuestro controlador de vista ya está lista.
Definición de las vistas de Ionic Framework
La última parte de nuestro www/js/app.js será para definir nuestras vistas. Esto se hace en el archivo AngularJS
configurar() así:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.config(función($stateProvider, $urlRouterProvider) { $stateProvider .estado("lista", { "url": "/lista", "templateUrl": "templates/list.html", "controlador": "MainController" }) .estado("item", { "url": "/item/:documentId/:documentRevision", "templateUrl": "templates/item.html", "controlador": "MainController" }); $urlRouterProvider.de lo contrario("lista"); }) |
Definimos dos vistas, una para todos los elementos de nuestra lista y otra para crear y actualizar nuevos elementos de la lista. El sitio artículo toma un valor opcional
id del documento y revisión del documento. Cuando están presentes, significa que vamos a actualizar un documento en particular.
Toda nuestra lógica AngularJS está completa ahora. Hemos inicializado nuestra base de datos, iniciado la sincronización, definido nuestras vistas y planificado la interacción
de nuestros puntos de vista.
Creación de una vista de lista
Aquí definiremos cómo se presentan los datos en la lista. En la sección www/plantillas/lista.html añada el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<botón clase="botón derecho botón-icono icono ion-plus"></botón> {{valor.nombre}} {{valor.apellido}} |
Al deslizar un elemento de la lista se nos presenta un botón de borrado que llamará a la función suprimir() de nuestro controlador.
Creación de una vista de formulario
Aquí definiremos los documentos que serán insertados o actualizados en nuestra base de datos. Esencialmente, esta vista es sólo un formulario. En su proyecto
www/templates/item.html añada el siguiente código:
Configuración de la pasarela de sincronización
PouchDB y Ionic Framework son sólo la mitad de la historia aquí. Claro que van a crear una buena aplicación de ejecución local, pero queremos que las cosas se sincronicen. El Couchbase Sync Gateway es nuestro punto final para esto y por supuesto PouchDB funciona muy bien con él.
Dentro de la sección sync-gateway-config.json añada lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
{ "log":["CRUD+", "REST+", "Cambios+", "Adjuntar+"], "bases de datos": { "base de datos de prueba": { "servidor":"morsa:datos", "sync":` función (doc) { canal (doc.canales); } `, "usuarios": { "INVITADO": { "desactivado": falso, "admin_canales": ["*"] } } } }, "CORS": { "Origen": ["http://localhost:9000"], "LoginOrigin": ["http://localhost:9000"], "Cabeceras": ["Tipo de contenido"], "MaxAge": 17280000 } } |
Esta es una de las configuraciones más básicas que existen. Algunas cosas a tener en cuenta al respecto:
- Utiliza walrus:data para el almacenamiento, que está en memoria y no persiste. No debe utilizarse para producción.
- Todos los datos se sincronizan a través del usuario GUEST, por lo que no hay autenticación aquí, pero podría haberla.
- Estamos arreglando los problemas de CORS permitiendo peticiones en localhost:9000 en caso de que quieras servir con Python para pruebas de navegador.
Probar la aplicación
En este punto todo nuestro código está en su lugar y nuestro Sync Gateway está listo para ser ejecutado. Inicie el Sync Gateway ejecutando lo siguiente en un archivo
Símbolo del sistema o Terminal:
1 2 3 |
/ruta/a/sincronizar/pasarela/papelera/sincronizar-pasarela /ruta/a/proyecto/sincronizar-pasarela-config.json |
La puerta de enlace de sincronización debería estar ahora en funcionamiento y puede validarlo visitando http://localhost:4984 en su navegador web.
Pruebas para Android
Con un dispositivo conectado o un simulador en ejecución, desde el símbolo del sistema o el terminal, ejecute los dos comandos siguientes para crear y
instalar el archivo APK:
1 2 3 4 |
iónico construya android adb instale -r plataformas/android/construya/salidas/apk/android-depurar.apk |
Pruebas para iOS
Hay dos buenas maneras de hacer esto. Usted puede construir el proyecto y abrirlo con Xcode, o puede construir y
emular la aplicación sin lanzar Xcode. El primero se puede hacer así:
1 2 3 |
iónico construya ios |
A continuación, abra el directorio platform/ios/ del proyecto e inicie el archivo de proyecto de Xcode.
Si has instalado el paquete ios-sim de Node Package Manager (NPM), puedes hacer lo siguiente:
1 2 3 4 |
iónico construya ios iónico emule ios |
Conclusión
Ya has visto que hay dos formas de utilizar Couchbase en tu aplicación móvil Android e iOS de Ionic Framework. Puedes utilizar el
Apache Cordova Couchbase plugin como se demuestra en
el series de blogs anterioreso puede
utilizar PouchDB. Ambos son opciones muy adecuadas cuando se trata de almacenamiento y sincronización de datos entre plataformas en tu aplicación.
Puede obtener el código fuente completo de esta entrada de blog a través de
nuestra Repositorio GitHub de Couchbase Labs.
Hola, interesante artículo. Conoces algún hosting para CouchDB para almacenar/sincronizar datos de aplicaciones?
Hola,
Este artículo habla de Couchbase. CouchDB es un software completamente diferente.
Puedes alojar Couchbase en casi cualquier sitio. Las soluciones de alojamiento más populares son AWS y Joyent, pero hay muchas más.
¿Responde esto a su pregunta?
Lo mejor,
Culpa mía, siempre cometo el error...
Estoy buscando un alojamiento de Couchbase realmente sencillo, algo como heroku por ejemplo...
Muchos tutoriales sobre PouchDB explican cómo usarlo localmente, pero no he encontrado ninguno que muestre la sincronización real entre dispositivos con un servidor (y algunas recomendaciones de alojamiento, seguridad...).
Todavía estoy un poco confundido sobre cómo utilizar PouchDB / Couchbase como almacenamiento primario para una aplicación, pero debo investigar / probar más ;)
Puede leer esto:
http://www.couchbase.com/2015…
Es la parte 1 de una serie de dos partes para conseguir que Couchbase Server y Couchbase Sync Gateway funcionen en AWS.
Lo mejor,
Lo comprobaré. Muchas gracias.
No hay problema. Cuéntenos lo que descubra :-)
Gracias señor, por este gran tutorial.
No hay problema.
Hola, señor,
Gracias lo he entendido todo bien.
Además, yo estaba tratando de añadir otra entrada es decir, la entrada de fecha. Lo suministré al parámetro y argumento de la función guardar.
Y estaba bien después de guardar en la base de datos, pero no mostrar el valor de la fecha en el modo de edición.
Gracias.
Hola, señor,
Al final lo solucioné incluyendo esto en la función get.
$scope.inputForm.Date = new Date($scope.inputForm.Date);
Hola, señor,
Gracias una vez más por el tutorial.
Me gustaría decir que me encuentro con este lanzamiento en la consola al probar la aplicación después de algún tiempo.
Estoy usando (windows, ionic, angularjs, chrome).
\" (nodo) advertencia: posible fuga de memoria EventEmitter detectado. 11 oyentes añadidos. Utilice emitter.setMaxListeners() para aumentar el límite \"
Gracias
Según Nolan Lawson, creador de PouchDB, se trata simplemente de una advertencia y no de un error:
http://pouchdb.com/errors.html…
Recomienda actualizar a PouchDB 5 y aumentar el límite si quieres que el error desaparezca.
Lo mejor,
Hola Nic,
Gracias por los tutoriales.
He probado tanto "Couchbase Lite PhoneGap" como "PouchDB + SQLite" como cliente para Sync Gateway.
Parece que "Couchbase Lite PhoneGap" tiene algunos problemas: https://github.com/couchbasela... y también PouchDB es más multiplataforma IMHO (podemos reutilizar el código en webapps también) - Espero que Couchbase Sync Gateway no rompa la integración con PouchDB y vise-versa.
He intentado actualizar tu ejemplo a la última versión de PouchDB 5.1.0 y he encontrado errores y problemas (creo que están relacionados con la integración CORS y también similares a este: https://github.com/pouchdb/pou…
¿Has probado la última versión de PouchDB 5.1.0 / o incluso la última nightly build que corrige algunos de los errores?
¿Podría proporcionar más información: utilizó intencionadamente la última versión 4.x: 4.0.3, debido a los errores anteriores u otros problemas?
Ejemplo para servicios PouchDB 5.x que yo escribí: https://gist.github.com/Danail…
Hola,
Escribí / publiqué este artículo sólo unos días antes del lanzamiento de la versión 5.x. No fue intencional usar una versión anterior. Hablé con Nolan Lawson, el creador de PouchDB, y me dijo que debería funcionar.
Haré algunas pruebas y te lo haré saber.
Lo mejor,
Gracias por su rápida respuesta.
He probado con la última versión "Couchbase Sync Gateway Community Edition 1.1.1" y "PouchDB 5.0.1". - antes estaba usando la imagen de Docker que no es la última versión (la última imagen docker es 1.1.0 https://hub.docker.com/r/couch... y tiene errores críticos - http://developer.couchbase.com….
La migración de su aplicación de prueba es sencilla: https://github.com/DanailMinch... y no necesita ningún cambio específico.
Así que los resultados son los mismos:
Cuando inicio la aplicación y en la aplicación:
1. insertar el primer registro
2. editar el mismo registro
3. suprimir el mismo registro
Puedo ver los cambios en http://localhost:4985/_admin/db/test-database
Pero, después de esto me aparecen algunos errores extraños en la consola de Sync Gateway:
2015-11-20T13:59:55.370Z Changes+: MultiChangesFeed: canales se expanden a channels.TimedSet{\"*\":0x0} ...
2015-11-20T13:59:55.370Z Changes: MultiChangesFeed hecho
2015-11-20T13:59:55.370Z Changes+: MultiChangesFeed: canales se expanden a channels.TimedSet{\"*\":0x0} ...
2015-11-20T13:59:55.370Z Changes+: MultiChangesFeed esperando...
2015-11-20T13:59:55.370Z Changes+: Esperando a que la cuenta de \"test-database\"\ pase de 6.
2015-11-20T13:59:55.761Z HTTP: #791: GET /?_nonce=1448027995207
2015-11-20T13:59:55.786Z HTTP: #792: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027995234
2015-11-20T13:59:55.787Z HTTP: #792: -> Falta 404 (0.4 ms)
2015-11-20T13:59:55.824Z HTTP: #793: POST /test-database/_revs_diff?_nonce=1448027995276
2015-11-20T13:59:55.839Z HTTP: #794: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027995290
2015-11-20T13:59:55.840Z HTTP: #794: -> Falta 404 (0.3 ms)
2015-11-20T13:59:55.859Z HTTP: #795: POST /test-database/_bulk_docs?_nonce=1448027995309
2015-11-20T13:59:55.860Z BulkDocs: Doc \"_local/pqPlGGz4hPigHnXAGLPSNg==\" -> 400 ID de documento no válido (400 Invalid doc ID)
2015-11-20T13:59:56.174Z HTTP: #796: GET /?_nonce=1448027995616
2015-11-20T13:59:56.200Z HTTP: #797: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027995646
2015-11-20T13:59:56.200Z HTTP: #797: -> Falta 404 (0.2 ms)
2015-11-20T13:59:56.231Z HTTP: #798: POST /test-database/_revs_diff?_nonce=1448027995683
2015-11-20T13:59:56.246Z HTTP: #799: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027995698
2015-11-20T13:59:56.247Z HTTP: #799: -> Falta 404 (0.3 ms)
2015-11-20T13:59:56.265Z HTTP: #800: POST /test-database/_bulk_docs?_nonce=1448027995718
2015-11-20T13:59:56.265Z BulkDocs: Doc \"_local/pqPlGGz4hPigHnXAGLPSNg==\" -> 400 ID de documento no válido (400 Invalid doc ID)
2015-11-20T13:59:57.988Z HTTP: #801: GET /?_nonce=1448027997429
2015-11-20T13:59:58.015Z HTTP: #802: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027997462
2015-11-20T13:59:58.015Z HTTP: #802: -> Falta 404 (0.4 ms)
2015-11-20T13:59:58.065Z HTTP: #803: POST /test-database/_revs_diff?_nonce=1448027997511
2015-11-20T13:59:58.087Z HTTP: #804: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027997531
2015-11-20T13:59:58.087Z HTTP: #804: -> Falta 404 (0.3 ms)
2015-11-20T13:59:58.106Z HTTP: #805: POST /test-database/_bulk_docs?_nonce=1448027997558
2015-11-20T13:59:58.106Z BulkDocs: Doc \"_local/pqPlGGz4hPigHnXAGLPSNg==\" -> 400 ID de documento no válido (400 Invalid doc ID)
2015-11-20T13:59:58.545Z HTTP: #806: GET /?_nonce=1448027997993
2015-11-20T13:59:58.574Z HTTP: #807: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027998022
2015-11-20T13:59:58.574Z HTTP: #807: -> Falta 404 (0.3 ms)
Que se mantiene en bucle y mi segundo registro es incapaz de sincronizar con la puerta de enlace.
Gracias por su respuesta.
He probado con la última versión de "Couchbase Sync Gateway Community Edition 1.1.1" y "PouchDB 5.0.1" (también con imágenes Docker).
Los resultados son los mismos:
Cuando inicio la aplicación y en la aplicación:
1. insertar el primer registro
2. editar el mismo registro
3. suprimir el mismo registro
Puedo ver los cambios en http://localhost:4985/_admin/db/test-database
Pero, después de esto me aparecen algunos errores extraños en la consola de Sync Gateway:
2015-11-20T13:59:55.370Z Changes+: MultiChangesFeed: canales se expanden a channels.TimedSet{\"*\":0x0} ...
2015-11-20T13:59:55.370Z Changes: MultiChangesFeed hecho
2015-11-20T13:59:55.370Z Changes+: MultiChangesFeed: canales se expanden a channels.TimedSet{\"*\":0x0} ...
2015-11-20T13:59:55.370Z Changes+: MultiChangesFeed esperando...
2015-11-20T13:59:55.370Z Changes+: Esperando a que la cuenta de \"test-database\"\ pase de 6.
2015-11-20T13:59:55.761Z HTTP: #791: GET /?_nonce=1448027995207
2015-11-20T13:59:55.786Z HTTP: #792: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027995234
2015-11-20T13:59:55.787Z HTTP: #792: -> Falta 404 (0.4 ms)
2015-11-20T13:59:55.824Z HTTP: #793: POST /test-database/_revs_diff?_nonce=1448027995276
2015-11-20T13:59:55.839Z HTTP: #794: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027995290
2015-11-20T13:59:55.840Z HTTP: #794: -> Falta 404 (0.3 ms)
2015-11-20T13:59:55.859Z HTTP: #795: POST /test-database/_bulk_docs?_nonce=1448027995309
2015-11-20T13:59:55.860Z BulkDocs: Doc \"_local/pqPlGGz4hPigHnXAGLPSNg==\" -> 400 ID de documento no válido (400 Invalid doc ID)
2015-11-20T13:59:56.174Z HTTP: #796: GET /?_nonce=1448027995616
2015-11-20T13:59:56.200Z HTTP: #797: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027995646
2015-11-20T13:59:56.200Z HTTP: #797: -> Falta 404 (0.2 ms)
2015-11-20T13:59:56.231Z HTTP: #798: POST /test-database/_revs_diff?_nonce=1448027995683
2015-11-20T13:59:56.246Z HTTP: #799: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027995698
2015-11-20T13:59:56.247Z HTTP: #799: -> Falta 404 (0.3 ms)
2015-11-20T13:59:56.265Z HTTP: #800: POST /test-database/_bulk_docs?_nonce=1448027995718
2015-11-20T13:59:56.265Z BulkDocs: Doc \"_local/pqPlGGz4hPigHnXAGLPSNg==\" -> 400 ID de documento no válido (400 Invalid doc ID)
2015-11-20T13:59:57.988Z HTTP: #801: GET /?_nonce=1448027997429
2015-11-20T13:59:58.015Z HTTP: #802: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027997462
2015-11-20T13:59:58.015Z HTTP: #802: -> Falta 404 (0.4 ms)
2015-11-20T13:59:58.065Z HTTP: #803: POST /test-database/_revs_diff?_nonce=1448027997511
2015-11-20T13:59:58.087Z HTTP: #804: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027997531
2015-11-20T13:59:58.087Z HTTP: #804: -> Falta 404 (0.3 ms)
2015-11-20T13:59:58.106Z HTTP: #805: POST /test-database/_bulk_docs?_nonce=1448027997558
2015-11-20T13:59:58.106Z BulkDocs: Doc \"_local/pqPlGGz4hPigHnXAGLPSNg==\" -> 400 ID de documento no válido (400 Invalid doc ID)
2015-11-20T13:59:58.545Z HTTP: #806: GET /?_nonce=1448027997993
2015-11-20T13:59:58.574Z HTTP: #807: GET /test-database/_local/pqPlGGz4hPigHnXAGLPSNg==?&_nonce=1448027998022
2015-11-20T13:59:58.574Z HTTP: #807: -> Falta 404 (0.3 ms)
Que se mantiene en bucle y mi segundo registro es incapaz de sincronizar con la puerta de enlace.
Hola de nuevo,
Parece que PouchDB 5.0.0 funciona con el proyecto, pero 5.1.0 no funciona.
He creado un problema aquí: https://github.com/pouchdb/pou…
Por favor, hazme saber si has conseguido actualizar a la última versión 5.1.0 o cualquier otra novedad, ¡gracias!
Estoy pensando en utilizar casi exactamente este paradigma para una solución que estoy desarrollando para niños con TDAH. Me encantaría usar Couchbase Sync para mantener los datos de los usuarios sincronizados entre la aplicación local de los usuarios en Ionic y la base de datos maestra en la nube. No estoy seguro de cómo la autenticación de usuario en las DBs trabajaría con / sincronizaría con un servicio CAS /OAuth 2 que será utilizado por Spring Security para autenticar las solicitudes de usuario fuera del entorno de base de datos desde el sitio web y / u otras funciones móviles. ¿Hay alguna manera de sincronizar las cuentas de usuario couchbase con otros servicios de autenticación como oauth o CAS o algún otro servicio basado en token? ¡Mi arquitectura original no era un diseño offline en primer lugar y yo sólo iba a utilizar el acceso basado en token a los servicios web a través de los componentes móviles y web, pero CouchBase con Sync se ve tan impresionante para hacer la sincronización de base de datos, quiero aprovechar eso! ¡Cualquier idea será apreciada! ¿Usted o couchbase proporcionan servicios de consultoría de arquitectura? ¡De todos modos, por favor, hágamelo saber acerca de la sincronización de cuentas de usuario!
BTW, estoy usando AWS y también leer a través del post http://www.couchbase.com/2015... que también es relevante para lo que estoy tratando de hacer. Imagina que con una versión web también y tratando de mantener los datos Y cuentas de usuario sincronizados a través de ambas plataformas....
Gracias,
Rich
Cuando dice CAS, ¿se refiere a Jasig CAS? No creo que sea un problema para montar esto junto con su solución de inicio de sesión único.
He mencionado su solicitud de asesoramiento arquitectónico a mi equipo. ¿Puede enviarme un correo electrónico services@couchbase.com. Sólo haz referencia a este post en él.
Lo mejor,
Nic, sí, me refería a JASIG CAS. Supongo que, en resumidas cuentas, sí, estoy intentando averiguar cuál es la mejor forma de integrar CB con una solución SSO basada en tokens. Enviaré un correo electrónico a su equipo de servicios, gracias.
Estupendo. Seguro que nos pondremos en contacto contigo :-)
Hola Nic,
Muchas gracias por este tutorial.
Aunque parece que tengo algunos problemas, cuando estoy tratando de guardar los documentos en mi sync_gateway (ya sea a través de morsa o un cubo en el servidor Couchbase ).
También estoy recibiendo una salida extraña de mi Sync Gateway (estoy usando el cubo \'default\'):
Tareks-MacBook-Pro:ionic-framework-pouchdb-master Tarek$ sync_gateway sync-gateway-config.json
2016-04-26T14:36:38.840+03:00 Activando registro: [CRUD+ REST+ Cambios+ Adjuntar+]
2016-04-26T14:36:38.840+03:00 ==== Couchbase Sync Gateway/1.1.1(10;2fff9eb) ====
2016-04-26T14:36:38.841+03:00 Configurado Go para usar las 4 CPUs; setenv GOMAXPROCS para anular esto
2016-04-26T14:36:38.841+03:00 Proceso configurado para permitir 5000 descriptores de archivo abiertos.
2016-04-26T14:36:38.841+03:00 Abriendo db /default como bucket \"default\", pool \"default\", servidor .
2016-04-26T14:36:38.841+03:00 Abriendo base de datos Couchbase por defecto en .
2016/04/26 14:36:38 Probando con http://127.0.0.1:8091/pools/default/bucketsStreaming/default
2016/04/26 14:36:38 Probando con el nodo seleccionado 0
2016/04/26 14:36:38 Obtenida nueva configuración para bucket por defecto.
2016/04/26 14:36:38 Probando con el nodo seleccionado 0
2016-04-26T14:36:38.987+03:00 Restablecer usuario invitado a config.
2016-04-26T14:36:38.987+03:00 Iniciando servidor admin en 127.0.0.1:4985
2016-04-26T14:36:38.991+03:00 Iniciando servidor en :4984 ...
2016-04-26T14:36:49.750+03:00 HTTP: #001: GET /default/?_nonce=1461670609748
2016-04-26T14:37:49.464+03:00 HTTP: #002: GET /default/?_nonce=1461670669460
2016-04-26T14:37:50.572+03:00 HTTP: #003: GET /default/?_nonce=1461670670570
2016-04-26T14:37:50.833+03:00 HTTP: #004: GET /default/?_nonce=1461670670831
2016-04-26T14:37:52.465+03:00 HTTP: #005: GET /default/?_nonce=1461670672463
2016-04-26T14:37:52.793+03:00 HTTP: #006: GET /default/?_nonce=1461670672792
2016-04-26T14:37:55.567+03:00 HTTP: #007: GET /default/?_nonce=1461670675566
2016-04-26T14:37:56.393+03:00 HTTP: #008: GET /default/?_nonce=1461670676392
2016-04-26T14:38:00.794+03:00 HTTP: #009: GET /default/?_nonce=1461670680792
2016-04-26T14:38:02.589+03:00 HTTP: #010: GET /default/?_nonce=1461670682587
…
Por favor, hágamelo saber si necesita más información de mi parte también.
Saludos cordiales,
Tarek M.
Hola Tarek,
No veo nada fuera de lo normal en tu registro de Sync Gateway. ¿Puede darme más información sobre los problemas que tiene al guardar?
Lo mejor,
Hola Nic,
Gracias por su rápida respuesta. El caso es que actualmente no puedo ver ningún documento nuevo en mi servidor de CouchBase (mi principal prioridad es ver los datos en los buckets en lugar de usar walrus). Así es como he configurado mi puerta de enlace de sincronización (actualmente en la versión 1.2):
{
\Log: [CRUD, REST, Changes, Attach],
\bases de datos: {
\...por defecto: {
\Servidor: http://localhost:8091,
\Por defecto,
\Sincronización:
,function (doc) {
canal (doc.canales);
}
{\i1}"usuarios".{\i} {
\"INVITADO": {
\deshabilitado: falso,
\"admin_channels": [\"*\"]
}
}
}
},
\ "CORS\": {
\"Origen": [\"http://localhost:9000\"],
\"LoginOrigin\": [\"http://localhost:9000\"],
\Encabezados: [\"Content-Type\"],
\"MaxAge": 17280000
}
}
Intenté añadir el nivel de registro en la puerta de enlace de sincronización, pero no pude ver ningún mensaje POST o PUT siendo llamado, ni pude verlos en la puerta de enlace de sincronización.
También he utilizado el comando: python -m SimpleHTTPServer 9000 para CORS.
¿tal vez me estoy perdiendo un paso o algo está mal configurado?
Gracias de antemano, realmente aprecio su ayuda :)
No estarás intentando usar Ionic Serve, Ionic Ionic-Live Reload o Ionic View, ¿verdad? No suelen funcionar con plugins nativos. Además, ¿qué dicen los registros de tu aplicación? Probablemente quieras empezar por ahí.
Lo mejor,
Hola Nic,
¡Muchas gracias! Inicialmente lo estaba probando en ionic serve, lo probé directamente en mi dispositivo móvil y funcionó sin problemas.
Sin embargo, los primeros intentos fracasaron porque mi dispositivo móvil y el servidor estaban conectados a redes diferentes, lo que causó cierta confusión.
Muchas gracias, Nic.
No hay problema.