Dirigible urbano es un popular servicio de mensajería y notificaciones. En la primera parte de este artículo veremos cómo configurar las notificaciones push de Urban Airship. En la parte 2 del post utilizaremos estas notificaciones para desencadenar réplicas en Couchbase Móvil.
Lo que necesitas
Puedes utilizar Urban Airship (UA) de forma gratuita. (Consulta la página web de UA para conocer los precios actuales.) Eso sí, tienes que registrar una cuenta.
- Relato de un dirigible urbano
- Una cuenta Firebase (requiere una cuenta de inicio de sesión de Google)
- Android Studio (o Xcode)
Parte 1 - Configuración del dirigible urbano
Abre un proyecto Android o iOS existente en tu IDE (o crea uno nuevo). Aquí voy a ilustrar el uso de Android.
Inicie sesión en su cuenta de UA. Vaya a la página Nueva aplicación. Escriba el nombre de su aplicación. Seleccione las plataformas que desea utilizar. (En este ejemplo elegiremos Android e iOS.) Al pulsar "Guardar" accederás a la guía de inicio rápido. (Si usted ya ha pasado por el inicio rápido y necesita un repaso de la configuración, puede encontrar los pasos para Android aquí y para iOS aquí.)
UA quickstart
Aquí se te ofrece una pestaña para cada plataforma seleccionada. Como ya hemos dicho, esta vez nos centraremos en construir para Android.
Sigue los pasos de inicio rápido de Urban Airship. Tengo algunos consejos para los problemas que encontré.
Pasos 1 y 2 del inicio rápido de Urban Airship
La guía de UA hace referencia al script build.gradle del proyecto, pero luego muestra la modificación del script build.gradle del módulo. Añadí el repositorio UA al script gradle de mi proyecto, y la dependencia UA al script gradle del módulo. Eso funcionó bien.
Busca el applicationID en el script gradle del módulo.
Paso 5 del inicio rápido de Urban Airship
Para crear su propia clase de aplicación, haga clic con el botón derecho del ratón en el área de aplicación del panel de navegación del proyecto y seleccione Nuevo > Clase Java. En la ventana emergente, establece el nombre de la clase. A continuación, para la Superclase introduce android.app.Application.
No olvide actualizar su archivo de manifiesto. Puede utilizar el nombre completo de su clase, o la forma abreviada que UA muestra. La forma completa se parece a esto:
1 2 |
<aplicación android:nombre="com.couchbase.cblite.android.cbpushsync.MyApplication" |
Paso 6 del inicio rápido de Urban Airship
UA utiliza Firebase Cloud Messaging (FCM). El paso seis tiene un enlace a más documentación de UA. Esta nueva página tiene instrucciones detalladas sobre cómo crear una clave API para tu app.
Las instrucciones de esa página bajo el título "Configurar el servicio FCM/GCM con Urban Airship" están un poco desfasadas. Encontrarás el área para introducir la clave API y el paquete al final de la guía de inicio rápido, en lugar de donde se indica en la documentación.
En un lugar, los documentos de la UA hacen referencia al "Número de proyecto de la API de Google". Esto es lo que FCM llama su ID de remitente.
Pruebas
El quickstart termina con un área de pruebas, sin muchas instrucciones. Si echas un vistazo al código incluido en tu subclase Application, verás que está habilitando las notificaciones de usuario. Para probar, construye tu aplicación e instálala en un emulador o dispositivo. (Yo probé ambos y funcionaron bien).
Introduce algo en el campo de texto y haz clic en "Enviar prueba". Debería aparecer un icono en el área de notificación de Android. Curiosamente, esto no incluye el texto introducido en el área de prueba.
Para la solución de problemas UA te dirige a un oscuro enlace "Consola de errores" en la esquina inferior derecha de la página de documentación. Desgraciadamente, el enlace me devolvió a la guía de inicio rápido.
Conclusión de la 1ª parte
Como has visto en los pasos anteriores, configurar Urban Airship fue bastante rápido. El inicio rápido muestra cómo enviar una notificación de alerta. Para activar la sincronización de datos en un cliente Couchbase Lite, tendremos que enviar una alerta silenciosa en su lugar, la parte 2 de este post cubrirá eso.
Parte 2 - Activación de la sincronización de datos desde la nube
En la parte 1 de este post se configura Urban Airship, en la parte 2 voy a mostrar una aplicación Android de ejemplo creada con Couchbase Lite que utiliza una notificación push de Urban Airship para activar la sincronización de datos desde la nube a un dispositivo móvil. Aquí "la nube" será un Pasarela de sincronización en una configuración de prueba. (Couchbase Lite y Sync Gateway son parte de la pila de Couchbase Mobile. Puedes leer sobre Couchbase Mobile aquí.)
Fondo
Couchbase Mobile sincroniza los datos usando réplicas unidireccionales. Puedes configurar las réplicas para que se ejecuten y finalicen inmediatamente una vez que los datos locales estén actualizados ("one-shot"), o para escuchar indefinidamente nuevos cambios ("continuous").
Hay algunas razones por las que podría querer utilizar un servicio como Urban Airship para activar la sincronización en lugar de configurar una replicación continua. Por ejemplo, una replicación continua "pull" (que recupera datos de la nube) necesita mantener una conexión de red abierta. Una conexión abierta causará necesariamente un cierto consumo de la batería del dispositivo, incluso mientras esté inactiva. Lo ideal sería que una aplicación sólo abriera una conexión cuando hubiera cambios que transferir.
Más allá de eso, los servicios de notificaciones push como Urban Airship suelen tener una serie de funciones avanzadas para dirigirse a grupos de dispositivos. UA puede darte una gran flexibilidad a la hora de gestionar cuándo se producen las operaciones. Además, si tu aplicación ya utiliza un servicio push, eso ya requiere su propia conexión de red abierta. Tiene sentido usarlo para activar Couchbase Lite en lugar de duplicar la red.
Este ejemplo mostrará cómo integrar Urban Airship. Voy a caminar a través de todas las piezas necesarias, para que pueda construir una aplicación totalmente funcional.
La aplicación
He aquí un vistazo a la aplicación en acción. La parte superior de la imagen muestra la aplicación en funcionamiento. La parte inferior muestra una notificación push enviada desde la línea de comandos. Cuando la aplicación recibe la notificación push, muestra un indicador de progreso, inicia una replicación pull de una sola vez y, a continuación, muestra los cambios recibidos en el documento en una vista de texto.
Para entender este ejemplo, echaremos un vistazo a cuatro clases, algunos de los "pegamentos" que las unen, y mostraremos cómo probar los resultados.
Clases requeridas por Urban Airship
Para utilizar Urban Airship (UA), necesitamos implementar dos clases, una subclase de Autopilot, y una subclase de AirshipReceiver.
Piloto automático
UA tiene que ser inicializado antes de su uso. Puede hacerlo de dos formas, o bien llamando a despegue
de la aplicación onCreate
o creando una subclase de Autopilot. Elegí hacer esto último. Como veremos, UA tiene una forma interesante de utilizar automáticamente nuestra subclase.
La clase es simple. No quiero mostrar nada en la barra de notificaciones. Yo uso esta clase para desactivar las notificaciones de usuario, y eso es todo.
Aquí está el listado completo de CBAutoPilot.java.
1 2 3 4 5 6 7 8 9 10 11 |
paquete com.couchbase.cblite.android.cbpushsync; importar com.urbanairship.Piloto automático; importar com.urbanairship.UAirship; público clase CBAutoPilot extiende Piloto automático { @Override público void onAirshipReady(UAirship dirigible) { dirigible.getPushManager().setUserNotificationsEnabled(falso); } } |
Para utilizar esta clase, UA emplea una técnica exclusiva de Android. Usted indica qué clase utilizar con una entrada en su archivo de manifiesto de Android. En mi caso, la entrada tiene este aspecto (colocada dentro del archivo aplicación
sección):
1 2 |
<meta-datos android:nombre="com.urbanairship.autopilot" android:valor="com.couchbase.cblite.android.cbpushsync.CBAutoPilot"/> |
Aquí es donde ocurre un poco de la magia de Android. UA incluye una clase de Proveedor de Contenido para automatizar la iniciación. Se garantiza que los Proveedores de Contenido se instancian antes de que la aplicación onCreate
es llamado. UA utiliza esto para incluir código para leer esta entrada de metadatos, instanciar la subclase y llamar al método onAirshipReady
método.
AirshipReceiver
Con UA inicializado y listo para funcionar, necesitamos proporcionar los ganchos para capturar y procesar las notificaciones. Para ello, implementar una subclase de AirshipReceiver. De nuevo, la clase es sencilla.
Aquí está el listado completo de CBAirshipReceiver.java.
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 |
paquete com.couchbase.cblite.android.cbpushsync; importar android.contenido.Contexto; importar android.soporte.anotación.NonNull; importar android.util.Registro; importar com.urbanairship.AirshipReceiver; importar com.urbanairship.pulse.PushMessage; público clase CBAirshipReceiver extiende AirshipReceiver { privado estático final Cadena TAG = "CBAirshipReceiver"; @Override protegido void onPushReceived(Contexto contexto, PushMessage mensaje, booleano notificaciónColocado en) { Registro.i(TAG, "Mensaje push recibido. Alerta: " + mensaje.getAlert() + ". notificación publicada: " + notificaciónColocado en); interruptor(mensaje.getAlert()) { caso "inicio": CBLHelper.getInstance().startReplication(); romper; caso "stop": CBLHelper.getInstance().stopReplication(); romper; caso "reset": CBLHelper.getInstance().reiniciar(); romper; por defecto: romper; } } @Override protegido void onChannelCreated(@NonNull Contexto contexto, @NonNull Cadena channelId) { Registro.i(TAG, "Canal creado. Canal Id:" + channelId + "."); } @Override protegido void onChannelUpdated(@NonNull Contexto contexto, @NonNull Cadena channelId) { Registro.i(TAG, "Canal actualizado. Canal Id:" + channelId + "."); } @Override protegido void onChannelRegistrationFailed(Contexto contexto) { Registro.i(TAG, "Falló el registro del canal".); } } |
Cuando lleguemos a probar la aplicación, veremos cómo UA le permite establecer el texto de alerta. He utilizado que aquí proporcionar algunas operaciones remotas diferentes. Una alerta puede iniciar y detener las réplicas. También incluí la capacidad, mediante el envío de "reset", para eliminar la base de datos. Hice eso porque una vez que se replican los datos, es persistente en el dispositivo. Apagar la aplicación no reinicia la base de datos local. En lugar de tener que añadir siempre nuevos documentos a través de Sync Gateway para mostrar que la replicación funciona, he añadido la posibilidad de borrar la base de datos del dispositivo y empezar de nuevo.
Te darás cuenta de algunos otros métodos anulados arriba. Todos esos métodos están declarados abstractos en la clase AirshipReceiver, así que tenemos que incluir al menos una implementación mínima. Resulta, sin embargo, que necesitamos conocer el ID del canal del dispositivo para enviarle un mensaje. Este ID de canal cambia a menudo. En un futuro post, mostraré cómo registro el ID para que una aplicación del lado del servidor pueda enviar al dispositivo. Por ahora, es útil registrar el ID para que podamos extraerlo y utilizarlo en las pruebas.
Las clases de aplicación
Los ganchos anteriores ponen en marcha UA, atrapan notificaciones y desencadenan acciones basadas en su contenido. Ahora echemos un vistazo a la aplicación en sí.
La aplicación consiste en una actividad configurada para que podamos ver el contenido de los documentos a medida que se extraen. La otra clase envuelve algunas de las funcionalidades de Couchbase Lite en un helper.
Actividad principal
En la actividad principal, quiero mostrar una barra de progreso mientras se producen las réplicas y, a continuación, mostrar el conjunto de documentos enviados.
Aquí está el listado completo de MainActivity.java
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
paquete com.couchbase.cblite.android.cbpushsync; importar android.os.Paquete; importar android.soporte.v7.aplicación.AppCompatActivity; importar android.soporte.v7.widget.Barra de herramientas; importar android.util.Registro; importar android.ver.Ver; importar android.widget.Barra de progreso; importar android.widget.Vista de texto; importar com.couchbase.lite.Base de datos; importar com.couchbase.lite.Documento; importar com.couchbase.lite.CambioDocumento; importar com.couchbase.lite.replicador.Replicación; importar com.couchbase.lite.replicador.ReplicationState; importar com.fasterxml.jackson.databind.ObjectMapper; importar java.io.IOException; público clase Actividad principal extiende AppCompatActivity { privado estático Cadena TAG = Actividad principal.clase.getSimpleName(); privado estático final ObjectMapper mapeador = nuevo ObjectMapper(); privado CBLHelper cblHelper = CBLHelper.getInstance(); privado Vista de texto documentView; privado Barra de progreso progressBar; @Override protegido void onCreate(Paquete savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.diseño.actividad_principal); Barra de herramientas barra de herramientas = (Barra de herramientas) findViewById(R.id.barra de herramientas); setSupportActionBar(barra de herramientas); documentView = (Vista de texto) findViewById(R.id.documentView); progressBar = (Barra de progreso) findViewById(R.id.progressBar); cblHelper.inicializar( nuevo Base de datos.ChangeListener() { @Override público void cambiado(Base de datos.Evento de cambio evento) { Registro.i(TAG, "Cambio de base de datos llamado: recuento - " + evento.obtenerCambios().talla()); si (!evento.isExternal()) { devolver; } Cadena json = ""; para (final CambioDocumento cambiar : evento.obtenerCambios()) { si (!cambiar.isCurrentRevision()) { continuar; } Documento changedDoc = cblHelper.getExistingDocument(cambiar.getDocumentId()); si (changedDoc == null) continuar; pruebe { json += mapeador.writeValueAsString(changedDoc.getProperties()); } captura (IOException e) { e.printStackTrace(); } } final Cadena texto = json; runOnUiThread(nuevo Ejecutable() { @Override público void ejecute() { documentView.setText(texto); } }); } }, nuevo Replicación.ChangeListener() { @Override público void cambiado(Replicación.Evento de cambio evento) { Registro.i(TAG, "Cambio de replicación llamado: " + evento.toString()); si (evento.getError() != null) devolver; si (evento.getTransition() == null) devolver; ReplicationState dest = evento.getTransition().getDestination(); final int replicationProgress = ((dest == ReplicationState.PARADA || dest == ReplicationState.PARADA) ? Ver.INVISIBLE : Ver.VISIBLE); runOnUiThread(nuevo Ejecutable() { @Override público void ejecute() { progressBar.setVisibility(replicationProgress); } }); } } ); } } |
El núcleo del código consiste en dos escuchadores de cambios, uno para la base de datos y otro para las réplicas. Cada interfaz de escucha define un único método cambiado
.
El receptor de cambios de documentos nos permite seguir las actualizaciones reales de los documentos. Una réplica puede cambiar más de un documento a la vez. El evento de cambio devuelve una lista de IDs de documentos. Haciendo un bucle sobre los IDs de los documentos, recuperamos cada documento directamente, traducimos el contenido JSON a una cadena, y lo añadimos al texto a mostrar. Los escuchadores de cambios se ejecutan en un subproceso en segundo plano. Para terminar, tenemos que manipular los elementos de la interfaz de usuario en el hilo principal. Esto se hace fácilmente con la función runOnUiThread
de la Actividad.
El otro listener nos permite mostrar un spinner de ocupado-espera (barra de progreso indefinida) dependiendo del estado de Replicación. Puede leer más sobre la monitorización del estado de replicación aquí.
La clase auxiliar de base de datos
A menudo envuelvo funciones de base de datos en una clase helper. Como sólo necesitamos una instancia del helper, utilizo un patrón singleton. Al igual que UA, quiero que el helper esté disponible antes de que se inicie la aplicación principal. Utilizo la misma técnica de poner el código en un Content Provider.
Aquí está el listado completo de CBLHelper.java.
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
paquete com.couchbase.cblite.android.cbpushsync; importar android.contenido.Proveedor de contenidos; importar android.contenido.Valores de contenido; importar android.base de datos.Cursor; importar android.red.Uri; importar android.os.Manipulador; importar android.os.Looper; importar android.soporte.anotación.NonNull; importar android.soporte.anotación.Anulable; importar android.util.Registro; importar com.couchbase.lite.CouchbaseLiteException; importar com.couchbase.lite.Base de datos; importar com.couchbase.lite.Documento; importar com.couchbase.lite.Director; importar com.couchbase.lite.android.AndroidContext; importar com.couchbase.lite.replicador.Replicación; importar java.io.IOException; importar java.red.URL; público clase CBLHelper extiende Proveedor de contenidos { público estático final Cadena TAG = "Push Sync"; privado estático Cadena DB = "db"; //private static String syncGateway = "http://localhost:4984"; privado estático Cadena syncGateway = "http://10.0.2.2:4984"; privado estático URL syncGatewayURL; privado Director director; privado Base de datos base de datos; privado Replicación extractor; privado Base de datos.ChangeListener databaseChangeListener; privado Replicación.ChangeListener replicationChangeListener; privado estático CBLHelper instancia; público estático CBLHelper getInstance() { devolver instancia; } @Override público booleano onCreate() { instancia = este; enableLogging(); pruebe { syncGatewayURL = nuevo URL(syncGateway + "/" + DB); director = nuevo Director(nuevo AndroidContext(getContext()), Director.OPCIONES_POR_DEFECTO); } captura (IOException ex) { ex.printStackTrace(); } devolver verdadero; } público void cerrarBaseDeDatos() { base de datos.cerrar(); } público void startReplication() { extractor.iniciar(); } público void stopReplication() { extractor.stop(); } público void reiniciar() { stopReplication(); pruebe { base de datos.borrar(); } captura (CouchbaseLiteException ex) { ex.printStackTrace(); } inicializar(databaseChangeListener, replicationChangeListener); } público void inicializar(Base de datos.ChangeListener doble, Replicación.ChangeListener rl) { pruebe { base de datos = director.getDatabase(DB); } captura (CouchbaseLiteException ex) { ex.printStackTrace(); } base de datos.addChangeListener(doble); databaseChangeListener = doble; extractor = base de datos.createPullReplication(syncGatewayURL); extractor.addChangeListener(rl); replicationChangeListener = rl; } público Documento getExistingDocument(Cadena documentID) { devolver base de datos.getExistingDocument(documentID); } // Registro privado void enableLogging() { Director.enableLogging(TAG, Registro.VERBOSE); Director.enableLogging(com.couchbase.lite.util.Registro.TAG, Registro.VERBOSE); Director.enableLogging(com.couchbase.lite.util.Registro.TAG_SYNC_ASYNC_TASK, Registro.VERBOSE); Director.enableLogging(com.couchbase.lite.util.Registro.TAG_SYNC, Registro.VERBOSE); Director.enableLogging(com.couchbase.lite.util.Registro.CONSULTA_ETIQUETA, Registro.VERBOSE); Director.enableLogging(com.couchbase.lite.util.Registro.TAG_VIEW, Registro.VERBOSE); Director.enableLogging(com.couchbase.lite.util.Registro.TAG_DATABASE, Registro.VERBOSE); } // Función de ayuda para enviar en el hilo UI privado void runOnUiThread(Ejecutable ejecutable) { nuevo Manipulador(Looper.getMainLooper()).Correo electrónico:(ejecutable); } // Anulaciones obligatorias @Nullable @Override público Cursor consulta(@NonNull Uri uri, @Nullable Cadena[] proyección, @Nullable Cadena selección, @Nullable Cadena[] selectionArgs, @Nullable Cadena sortOrder) { devolver null; } @Nullable @Override público Cadena getType(@NonNull Uri uri) { devolver null; } @Nullable @Override público Uri insertar(@NonNull Uri uri, @Nullable Valores de contenido valores) { devolver null; } @Override público int borrar(@NonNull Uri uri, @Nullable Cadena selección, @Nullable Cadena[] selectionArgs) { devolver 0; } @Override público int actualización(@NonNull Uri uri, @Nullable Valores de contenido valores, @Nullable Cadena selección, @Nullable Cadena[] selectionArgs) { devolver 0; } } |
Puedes ver que esta clase sólo forma una fina envoltura. Retenemos una instancia de la clase durante onCreate
que se convierte en nuestro singleton. Algunas otras configuraciones básicas ocurren, como habilitar el registro y crear un gestor de base de datos. Escribí un inicializar
utilizado para abrir la base de datos, preparar la replicación pull y adjuntar los dos escuchadores de cambios. Recuerde que esto es llamado desde nuestra clase Activity. (Nota: Puedes tener más de un receptor de cambios para cada tipo. Couchbase mantiene una lista de todos los escuchadores añadidos, no sólo del último). Los otros métodos de la base de datos sólo proporcionan atajos simples.
Un proveedor de contenidos tiene varios métodos obligatorios que implementar. Tenemos que proporcionar stubs para ellos, que se ven en los últimos cinco métodos.
El manifiesto de Android
Por último, sólo para mostrar cómo esto se une y las diversas partes se exponen, he incluido el archivo de manifiesto de Android para el proyecto.
Aquí está el listado completo de AndroidManifest.xml.
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 |
<?xml versión="1.0" codificación="utf-8"?> <manifestar xmlns:android="http://schemas.android.com/apk/res/android" paquete="com.couchbase.cblite.android.cbpushsync"> <aplicación android:allowBackup="true" android:icono="@mipmap/ic_launcher" android:etiqueta="@string/nombre_app" android:soportaRtl="true" android:tema="@style/AppTheme"> <meta-datos android:nombre="com.urbanairship.autopilot" android:valor="com.couchbase.cblite.android.cbpushsync.CBAutoPilot"/> <actividad android:nombre=".MainActivity" android:etiqueta="@string/nombre_app" android:tema="@style/AppTheme.NoActionBar"> <intento-filtro> <acción android:nombre="android.intent.action.MAIN" /> <categoría android:nombre="android.intent.category.LAUNCHER" /> </intento-filtro> </actividad> <receptor android:nombre=".CBAirshipReceiver" android:exportado="falso"> <intento-filtro> <acción android:nombre="com.urbanairship.push.CHANNEL_UPDATED" /> <acción android:nombre="com.urbanairship.push.OPENED" /> <acción android:nombre="com.urbanairship.push.RECEIVED" /> <acción android:nombre="com.urbanairship.push.DISMISSED" /> <categoría android:nombre="${applicationId}" /> </intento-filtro> </receptor> <proveedor android:autoridades="${applicationId}.dbhelper" android:exportado="falso" android:habilitado="true" android:nombre=".CBLHelper" /> </aplicación> </manifestar> |
La biblioteca UA viene con su propio archivo de manifiesto. El sistema de compilación de Android integra todos los diferentes archivos de manifiesto para crear el archivo final. El archivo de manifiesto de la biblioteca UA es donde encontrarás las entradas para el proveedor de contenido que arranca la biblioteca.
Pasarela de sincronización
Para probar la aplicación, utilicé Sync Gateway con la base de datos integrada Walrus. Walrus es una base de datos en memoria normalmente se utiliza sólo para pruebas. Esto ahorra la molestia de configurar una instancia back-end de Couchbase Server.
Aquí está la lista completa del archivo de configuración de Sync Gateway.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ "log": ["HTTP+"], "adminInterface": "127.0.0.1:4985", "interfaz": "127.0.0.1:4984", "CORS": { "origen":["*"], "loginorigin":["*"], "cabeceras":["Tipo de contenido"], "maxAge": 1728000 }, "bases de datos": { "db": { "servidor": "morsa:", "usuarios": { "INVITADO": {"desactivado": falso, "admin_canales": ["*"] } } } } } |
Esto le dice a Sync Gateway para escuchar sólo en el localhost
aceptar cualquier petición de origen cruzado, y habilita el GUEST especial con acceso a todos los canales. Es una muy buena configuración de propósito general para empezar a asegurarse de que todo está funcionando.
Usted puede haber notado que usamos 10.0.2.2 como la dirección IP para Sync Gateway en la aplicación Android. El emulador estándar que viene con Android Studio asigna esto automáticamente a la máquina de alojamiento de localhost
. Si utilizas un emulador diferente (Genymotion es otro de los más populares), asegúrate de buscar qué dirección IP utilizar, ya que difieren.
Si desea obtener más información acerca de la configuración de Sync Gateway en su equipo de desarrollo, o cómo trabajar con él desde la línea de comandos, eche un vistazo a esto serie de blogs.
Pruebas
Para probarlo todo y grabar la animación que se muestra al principio del blog, ejecuto tanto el emulador de Android como Sync Gateway en una misma máquina. A continuación, envío notificaciones push a UA a través de su API REST.
Para preparar algo interesante, primero añado un documento a Sync Gateway. He aquí un comando shell para hacerlo.
1 |
$ rizo -X PUT -H Content-Type: application/json' -H 'Accept: application/json' -d '{ "test" : "UA", "channels": "public" }' http://localhost:4984/db/doc |
(Más información aquí).
Con un nuevo documento en la base de datos de Sync Gateway y la aplicación en funcionamiento, sólo queda activar una replicación pull para ver la acción.
Aquí está el rizo
para enviar una señal de "inicio". Recordemos que extraigo el valor de la parte "alerta" de la notificación para desencadenar acciones.
1 |
$ rizo https://ir.urbanairship.com/api/pulse -u appKey:appMasterSecret' -X POST -H Content-Type: application/json' -H 'Accept: application/vnd.urbanairship+json; version=3;' -d { "audiencia": { "android_channel": "3110bc81-1c7b-4ef8-a7a3-7c56aab19f08" }, "notification" : { "alert": "start" }, "device_types": "all" }' |
Tendrás que proporcionar tu propia clave de aplicación y el secreto maestro de la aplicación anterior. También es necesario mirar los archivos de registro para ver el valor del canal para entrar en "android_channel". Eso cambia con bastante regularidad. Desafortunadamente UA no hace mucho para indicar esto. Si encuentras que las notificaciones push no parecen tener ningún efecto, comprueba el valor del canal.
Después de publicar en UA, deberías ver una respuesta como esta.
1 |
{"ok":verdadero,"operation_id":"2a6c0edf-e5d0-4b4d-b762-ad5c4478c291","push_ids":["1951019a-2b7f-4f1b-8888-e87047a1feec"],"message_ids":[],"content_urls":[]} |
Y, por último, para restablecer una base de datos en blanco y volver a intentarlo, puedes publicar esto.
1 |
$ rizo https://ir.urbanairship.com/api/pulse -u appKey:appMasterSecret' -X POST -H Content-Type: application/json' -H 'Accept: application/vnd.urbanairship+json; version=3;' -d { "audiencia": { "android_channel": "3110bc81-1c7b-4ef8-a7a3-7c56aab19f08" }, "notification" : { "alert": "reset" }, "device_types": "all" }' |
Conclusión
Esto es todo para preparar nuestra aplicación Android para realizar réplicas basadas en notificaciones push. Asegúrese de revisar esta entrada sobre la supervisión de la fuente de cambios de Sync Gateway.
Posdata
Descargar Couchbase y Sync Gateway aquí. Consulte nuestro documentación para saber cómo añadir Couchbase Lite a un proyecto.
Consulte más recursos en nuestra portal para desarrolladores y síganos en Twitter @CouchbaseDev.
Puede enviar preguntas a nuestro foros. Y participamos activamente en Stack Overflow.
Envíame tus preguntas, comentarios, temas que te gustaría ver, etc. a Twitter. @HodGreeley.
[...] Nota: Puedes leer sobre la configuración de Urban Airship en esta entrada del blog. [...]