{"id":2515,"date":"2017-04-23T16:14:25","date_gmt":"2017-04-23T23:14:25","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2515"},"modified":"2024-01-12T12:26:11","modified_gmt":"2024-01-12T20:26:11","slug":"getting-started-with-urban-airship-push-notifications","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/getting-started-with-urban-airship-push-notifications\/","title":{"rendered":"Primeros pasos con las notificaciones push de Urban Airship"},"content":{"rendered":"<p style=\"text-align: center\"><img decoding=\"async\" style=\"max-width: 30% ! important\" src=\"\/wp-content\/original-assets\/2017\/january\/getting-started-with-urban-airship-push-notifications\/urban-airship-logo-blue.png\" alt=\"Urban Airship Logo\" align=\"middle\" \/><\/p>\n<p><a href=\"https:\/\/www.urbanairship.com\/\">Dirigible urbano<\/a> es un popular servicio de mensajer\u00eda y notificaciones. <span style=\"font-weight: 400\">\u00a0En la primera parte de este art\u00edculo veremos c\u00f3mo configurar las notificaciones push de Urban Airship. En la parte 2 del post utilizaremos estas notificaciones para<\/span> desencadenar r\u00e9plicas en <a href=\"https:\/\/www.couchbase.com\/blog\/es\/developers\/mobile\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">Couchbase M\u00f3vil<\/a>.<\/p>\n<h2>Lo que necesitas<\/h2>\n<p>Puedes utilizar Urban Airship (UA) de forma gratuita. (Consulta la p\u00e1gina web de UA para conocer los precios actuales.) Eso s\u00ed, tienes que registrar una cuenta.<\/p>\n<ul>\n<li>Relato de un dirigible urbano<\/li>\n<li>Una cuenta Firebase (requiere una cuenta de inicio de sesi\u00f3n de Google)<\/li>\n<li>Android Studio (o Xcode)<\/li>\n<\/ul>\n<h2>Parte 1 - Configuraci\u00f3n del dirigible urbano<\/h2>\n<p>Abre un proyecto Android o iOS existente en tu IDE (o crea uno nuevo). Aqu\u00ed voy a ilustrar el uso de Android.<\/p>\n<p>Inicie sesi\u00f3n en su cuenta de UA. Vaya a la p\u00e1gina Nueva aplicaci\u00f3n. Escriba el nombre de su aplicaci\u00f3n. Seleccione las plataformas que desea utilizar. (En este ejemplo elegiremos Android e iOS.) Al pulsar \"Guardar\" acceder\u00e1s a la gu\u00eda de inicio r\u00e1pido.  (Si usted ya ha pasado por el inicio r\u00e1pido y necesita un repaso de la configuraci\u00f3n, puede encontrar los pasos para Android\u00a0<a href=\"https:\/\/docs.urbanairship.com\/platform\/android\/\">aqu\u00ed<\/a>\u00a0y para iOS <a href=\"https:\/\/docs.urbanairship.com\/platform\/ios\/\">aqu\u00ed<\/a>.)<\/p>\n<p style=\"text-align: center\"><img decoding=\"async\" style=\"max-width: 70% ! important\" src=\"\/wp-content\/original-assets\/2017\/january\/getting-started-with-urban-airship-push-notifications\/urban-airship---new-app.png\" alt=\"Urban Airship New Application Dialog\" align=\"middle\" \/><\/p>\n<h3>UA quickstart<\/h3>\n<p>Aqu\u00ed se te ofrece una pesta\u00f1a para cada plataforma seleccionada. Como ya hemos dicho, esta vez nos centraremos en construir para Android.<\/p>\n<p>Sigue los pasos de inicio r\u00e1pido de Urban Airship. Tengo algunos consejos para los problemas que encontr\u00e9.<\/p>\n<h4>Pasos 1 y 2 del inicio r\u00e1pido de Urban Airship<\/h4>\n<p>La gu\u00eda de UA hace referencia al script build.gradle del proyecto, pero luego muestra la modificaci\u00f3n del script build.gradle del m\u00f3dulo. A\u00f1ad\u00ed el repositorio UA al script gradle de mi proyecto, y la dependencia UA al script gradle del m\u00f3dulo. Eso funcion\u00f3 bien.<\/p>\n<p>Busca el applicationID en el script gradle del m\u00f3dulo.<\/p>\n<h4>Paso 5 del inicio r\u00e1pido de Urban Airship<\/h4>\n<p>Para crear su propia clase de aplicaci\u00f3n, haga clic con el bot\u00f3n derecho del rat\u00f3n en el \u00e1rea de aplicaci\u00f3n del panel de navegaci\u00f3n del proyecto y seleccione Nuevo &gt; Clase Java. En la ventana emergente, establece el nombre de la clase. A continuaci\u00f3n, para la Superclase introduce android.app.Application.<\/p>\n<p style=\"text-align: center\"><img decoding=\"async\" style=\"max-width: 50% ! important\" src=\"\/wp-content\/original-assets\/2017\/january\/getting-started-with-urban-airship-push-notifications\/screen-shot-2017-01-28-at-3.37.30-pm.png\" alt=\"Creating an Application subclass\" align=\"middle\" \/><\/p>\n<p>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:<\/p>\n<pre class=\"lang:default decode:true\">    &lt;application\r\n        android:name=\"com.couchbase.cblite.android.cbpushsync.MyApplication\"<\/pre>\n<h4>Paso 6 del inicio r\u00e1pido de Urban Airship<\/h4>\n<p>UA utiliza Firebase Cloud Messaging (FCM). El paso seis tiene un enlace a m\u00e1s documentaci\u00f3n de UA. Esta nueva p\u00e1gina tiene instrucciones detalladas sobre c\u00f3mo crear una clave API para tu app.<\/p>\n<p>Las instrucciones de esa p\u00e1gina bajo el t\u00edtulo \"Configurar el servicio FCM\/GCM con Urban Airship\" est\u00e1n un poco desfasadas. Encontrar\u00e1s el \u00e1rea para introducir la clave API y el paquete al final de la gu\u00eda de inicio r\u00e1pido, en lugar de donde se indica en la documentaci\u00f3n.<\/p>\n<p>En un lugar, los documentos de la UA hacen referencia al \"N\u00famero de proyecto de la API de Google\". Esto es lo que FCM llama su ID de remitente.<\/p>\n<h2>Pruebas<\/h2>\n<p>El quickstart termina con un \u00e1rea de pruebas, sin muchas instrucciones. Si echas un vistazo al c\u00f3digo incluido en tu subclase Application, ver\u00e1s que est\u00e1 habilitando las notificaciones de usuario. Para probar, construye tu aplicaci\u00f3n e inst\u00e1lala en un emulador o dispositivo. (Yo prob\u00e9 ambos y funcionaron bien).<\/p>\n<p style=\"text-align: center\"><img decoding=\"async\" style=\"max-width: 70% ! important\" src=\"\/wp-content\/original-assets\/2017\/january\/getting-started-with-urban-airship-push-notifications\/screen-shot-2017-01-28-at-4.15.18-pm.png\" alt=\"Urban Airship Test Panel\" align=\"middle\" \/><\/p>\n<p>Introduce algo en el campo de texto y haz clic en \"Enviar prueba\". Deber\u00eda aparecer un icono en el \u00e1rea de notificaci\u00f3n de Android. Curiosamente, esto no incluye el texto introducido en el \u00e1rea de prueba.<\/p>\n<p>Para la soluci\u00f3n de problemas UA te dirige a un oscuro enlace \"Consola de errores\" en la esquina inferior derecha de la p\u00e1gina de documentaci\u00f3n. Desgraciadamente, el enlace me devolvi\u00f3 a la gu\u00eda de inicio r\u00e1pido.<\/p>\n<h2>Conclusi\u00f3n de la 1\u00aa parte<\/h2>\n<p><span style=\"font-weight: 400\">Como has visto en los pasos anteriores, configurar Urban Airship fue bastante r\u00e1pido. El inicio r\u00e1pido muestra c\u00f3mo enviar una notificaci\u00f3n de alerta. Para activar la sincronizaci\u00f3n de datos en un cliente Couchbase Lite, tendremos que enviar una alerta silenciosa en su lugar, la parte 2 de este post cubrir\u00e1 eso.<\/span><\/p>\n<h2>Parte 2 - Activaci\u00f3n de la sincronizaci\u00f3n de datos desde la nube<\/h2>\n<p><span style=\"font-weight: 400\">En la parte 1 de este post se configura Urban Airship, en la parte 2 voy a mostrar<\/span> una aplicaci\u00f3n Android de ejemplo creada con <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/current\/guides\/couchbase-lite\/index.html?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">Couchbase Lite<\/a> que utiliza una notificaci\u00f3n push de Urban Airship para activar la sincronizaci\u00f3n de datos desde la nube a un dispositivo m\u00f3vil. Aqu\u00ed \"la nube\" ser\u00e1 un <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/current\/guides\/sync-gateway\/index.html?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">Pasarela de sincronizaci\u00f3n<\/a> en una configuraci\u00f3n de prueba. (Couchbase Lite y Sync Gateway son parte de la pila de Couchbase Mobile. Puedes leer sobre Couchbase Mobile <a href=\"https:\/\/www.couchbase.com\/blog\/es\/developers\/mobile\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">aqu\u00ed<\/a>.)<\/p>\n<h2>Fondo<\/h2>\n<p>Couchbase Mobile sincroniza los datos usando r\u00e9plicas unidireccionales. Puedes configurar las r\u00e9plicas para que se ejecuten y finalicen inmediatamente una vez que los datos locales est\u00e9n actualizados (\"one-shot\"), o para escuchar indefinidamente nuevos cambios (\"continuous\").<\/p>\n<p>Hay algunas razones por las que podr\u00eda querer utilizar un servicio como Urban Airship para activar la sincronizaci\u00f3n en lugar de configurar una replicaci\u00f3n continua. Por ejemplo, una replicaci\u00f3n continua \"pull\" (que recupera datos de la nube) necesita mantener una conexi\u00f3n de red abierta. Una conexi\u00f3n abierta causar\u00e1 necesariamente un cierto consumo de la bater\u00eda del dispositivo, incluso mientras est\u00e9 inactiva. Lo ideal ser\u00eda que una aplicaci\u00f3n s\u00f3lo abriera una conexi\u00f3n cuando hubiera cambios que transferir.<\/p>\n<p>M\u00e1s all\u00e1 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\u00e1ndo se producen las operaciones. Adem\u00e1s, si tu aplicaci\u00f3n ya utiliza un servicio push, eso ya requiere su propia conexi\u00f3n de red abierta. Tiene sentido usarlo para activar Couchbase Lite en lugar de duplicar la red.<\/p>\n<p>Este ejemplo mostrar\u00e1 c\u00f3mo integrar Urban Airship. Voy a caminar a trav\u00e9s de todas las piezas necesarias, para que pueda construir una aplicaci\u00f3n totalmente funcional.<\/p>\n<h2>La aplicaci\u00f3n<\/h2>\n<p>He aqu\u00ed un vistazo a la aplicaci\u00f3n en acci\u00f3n. La parte superior de la imagen muestra la aplicaci\u00f3n en funcionamiento. La parte inferior muestra una notificaci\u00f3n push enviada desde la l\u00ednea de comandos. Cuando la aplicaci\u00f3n recibe la notificaci\u00f3n push, muestra un indicador de progreso, inicia una replicaci\u00f3n pull de una sola vez y, a continuaci\u00f3n, muestra los cambios recibidos en el documento en una vista de texto.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-3417\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/04\/CBPushSync.gif\" alt=\"\" width=\"366\" height=\"544\" \/>Para entender este ejemplo, echaremos un vistazo a cuatro clases, algunos de los \"pegamentos\" que las unen, y mostraremos c\u00f3mo probar los resultados.<\/p>\n<h2>Clases requeridas por Urban Airship<\/h2>\n<p>Para utilizar Urban Airship (UA), necesitamos implementar dos clases, una subclase de Autopilot, y una subclase de AirshipReceiver.<\/p>\n<h3>Piloto autom\u00e1tico<\/h3>\n<p>UA tiene que ser inicializado antes de su uso. Puede hacerlo de dos formas, o bien llamando a <code>despegue<\/code> de la aplicaci\u00f3n <code>onCreate<\/code> o creando una subclase de Autopilot. Eleg\u00ed hacer esto \u00faltimo. Como veremos, UA tiene una forma interesante de utilizar autom\u00e1ticamente nuestra subclase.<\/p>\n<p>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.<\/p>\n<p>Aqu\u00ed est\u00e1 el listado completo de CBAutoPilot.java.<\/p>\n<pre class=\"lang:java decode:true\">package com.couchbase.cblite.android.cbpushsync;\r\n\r\nimport com.urbanairship.Autopilot;\r\nimport com.urbanairship.UAirship;\r\n\r\npublic class CBAutoPilot extends Autopilot {\r\n    @Override\r\n    public void onAirshipReady(UAirship airship) {\r\n        airship.getPushManager().setUserNotificationsEnabled(false);\r\n    }\r\n}<\/pre>\n<p>Para utilizar esta clase, UA emplea una t\u00e9cnica exclusiva de Android. Usted indica qu\u00e9 clase utilizar con una entrada en su archivo de manifiesto de Android. En mi caso, la entrada tiene este aspecto (colocada dentro del archivo <code>aplicaci\u00f3n<\/code> secci\u00f3n):<\/p>\n<pre class=\"lang:default decode:true\">        &lt;meta-data android:name=\"com.urbanairship.autopilot\"\r\n            android:value=\"com.couchbase.cblite.android.cbpushsync.CBAutoPilot\"\/&gt;\r\n<\/pre>\n<p>Aqu\u00ed es donde ocurre un poco de la magia de Android. UA incluye una clase de Proveedor de Contenido para automatizar la iniciaci\u00f3n. Se garantiza que los Proveedores de Contenido se instancian antes de que la aplicaci\u00f3n <code>onCreate<\/code> es llamado. UA utiliza esto para incluir c\u00f3digo para leer esta entrada de metadatos, instanciar la subclase y llamar al m\u00e9todo <code>onAirshipReady<\/code> m\u00e9todo.<\/p>\n<h3>AirshipReceiver<\/h3>\n<p>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.<\/p>\n<p>Aqu\u00ed est\u00e1 el listado completo de CBAirshipReceiver.java.<\/p>\n<pre class=\"lang:java decode:true\">package com.couchbase.cblite.android.cbpushsync;\r\n\r\nimport android.content.Context;\r\nimport android.support.annotation.NonNull;\r\nimport android.util.Log;\r\n\r\nimport com.urbanairship.AirshipReceiver;\r\nimport com.urbanairship.push.PushMessage;\r\n\r\npublic class CBAirshipReceiver extends AirshipReceiver {\r\n    private static final String TAG = \"CBAirshipReceiver\";\r\n\r\n    @Override\r\n    protected void onPushReceived(Context context, PushMessage message, boolean notificationPosted) {\r\n        Log.i(TAG, \"Received push message. Alert: \" + message.getAlert() + \". posted notification: \" + notificationPosted);\r\n\r\n        switch(message.getAlert()) {\r\n            case \"start\":\r\n                CBLHelper.getInstance().startReplication();\r\n                break;\r\n            case \"stop\":\r\n                CBLHelper.getInstance().stopReplication();\r\n                break;\r\n            case \"reset\":\r\n                CBLHelper.getInstance().reset();\r\n                break;\r\n            default:\r\n                break;\r\n        }\r\n    }\r\n\r\n    @Override\r\n    protected void onChannelCreated(@NonNull Context context, @NonNull String channelId) {\r\n        Log.i(TAG, \"Channel created. Channel Id:\" + channelId + \".\");\r\n    }\r\n\r\n    @Override\r\n    protected void onChannelUpdated(@NonNull Context context, @NonNull String channelId) {\r\n        Log.i(TAG, \"Channel updated. Channel Id:\" + channelId + \".\");\r\n    }\r\n\r\n    @Override\r\n    protected void onChannelRegistrationFailed(Context context) {\r\n        Log.i(TAG, \"Channel registration failed.\");\r\n    }\r\n}\r\n<\/pre>\n<p>Cuando lleguemos a probar la aplicaci\u00f3n, veremos c\u00f3mo UA le permite establecer el texto de alerta. He utilizado que aqu\u00ed proporcionar algunas operaciones remotas diferentes. Una alerta puede iniciar y detener las r\u00e9plicas. Tambi\u00e9n inclu\u00ed la capacidad, mediante el env\u00edo 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\u00f3n no reinicia la base de datos local. En lugar de tener que a\u00f1adir siempre nuevos documentos a trav\u00e9s de Sync Gateway para mostrar que la replicaci\u00f3n funciona, he a\u00f1adido la posibilidad de borrar la base de datos del dispositivo y empezar de nuevo.<\/p>\n<p>Te dar\u00e1s cuenta de algunos otros m\u00e9todos anulados arriba. Todos esos m\u00e9todos est\u00e1n declarados abstractos en la clase AirshipReceiver, as\u00ed que tenemos que incluir al menos una implementaci\u00f3n m\u00ednima. 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\u00e9 c\u00f3mo registro el ID para que una aplicaci\u00f3n del lado del servidor pueda enviar al dispositivo. Por ahora, es \u00fatil registrar el ID para que podamos extraerlo y utilizarlo en las pruebas.<\/p>\n<h2>Las clases de aplicaci\u00f3n<\/h2>\n<p>Los ganchos anteriores ponen en marcha UA, atrapan notificaciones y desencadenan acciones basadas en su contenido. Ahora echemos un vistazo a la aplicaci\u00f3n en s\u00ed.<\/p>\n<p>La aplicaci\u00f3n 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.<\/p>\n<h3>Actividad principal<\/h3>\n<p>En la actividad principal, quiero mostrar una barra de progreso mientras se producen las r\u00e9plicas y, a continuaci\u00f3n, mostrar el conjunto de documentos enviados.<\/p>\n<p>Aqu\u00ed est\u00e1 el listado completo de MainActivity.java<\/p>\n<pre class=\"lang:java decode:true\">package com.couchbase.cblite.android.cbpushsync;\r\n\r\nimport android.os.Bundle;\r\nimport android.support.v7.app.AppCompatActivity;\r\nimport android.support.v7.widget.Toolbar;\r\nimport android.util.Log;\r\nimport android.view.View;\r\nimport android.widget.ProgressBar;\r\nimport android.widget.TextView;\r\n\r\nimport com.couchbase.lite.Database;\r\nimport com.couchbase.lite.Document;\r\nimport com.couchbase.lite.DocumentChange;\r\nimport com.couchbase.lite.replicator.Replication;\r\nimport com.couchbase.lite.replicator.ReplicationState;\r\nimport com.fasterxml.jackson.databind.ObjectMapper;\r\n\r\nimport java.io.IOException;\r\n\r\npublic class MainActivity extends AppCompatActivity {\r\n    private static String TAG = MainActivity.class.getSimpleName();\r\n    private static final ObjectMapper mapper = new ObjectMapper();\r\n\r\n    private CBLHelper cblHelper = CBLHelper.getInstance();\r\n    private TextView documentView;\r\n    private ProgressBar progressBar;\r\n\r\n    @Override\r\n    protected void onCreate(Bundle savedInstanceState) {\r\n        super.onCreate(savedInstanceState);\r\n        setContentView(R.layout.activity_main);\r\n        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);\r\n        setSupportActionBar(toolbar);\r\n\r\n        documentView = (TextView) findViewById(R.id.documentView);\r\n        progressBar = (ProgressBar) findViewById(R.id.progressBar);\r\n\r\n        cblHelper.initialize(\r\n            new Database.ChangeListener() {\r\n                @Override\r\n                public void changed(Database.ChangeEvent event) {\r\n                    Log.i(TAG, \"Database change called: count - \" + event.getChanges().size());\r\n\r\n                    if (!event.isExternal()) {\r\n                        return;\r\n                    }\r\n\r\n                    String json = \"\";\r\n\r\n                    for (final DocumentChange change : event.getChanges()) {\r\n                        if (!change.isCurrentRevision()) {\r\n                            continue;\r\n                        }\r\n\r\n                        Document changedDoc = cblHelper.getExistingDocument(change.getDocumentId());\r\n\r\n                        if (changedDoc == null) continue;\r\n\r\n                        try {\r\n                            json += mapper.writeValueAsString(changedDoc.getProperties());\r\n                        } catch (IOException e) {\r\n                            e.printStackTrace();\r\n                        }\r\n                    }\r\n\r\n                    final String text = json;\r\n\r\n                    runOnUiThread(new Runnable() {\r\n                        @Override\r\n                        public void run() {\r\n                            documentView.setText(text);\r\n                        }\r\n                    });\r\n                }\r\n            },\r\n            new Replication.ChangeListener() {\r\n                @Override\r\n                public void changed(Replication.ChangeEvent event) {\r\n                    Log.i(TAG, \"Replication change called: \" + event.toString());\r\n\r\n                    if (event.getError() != null) return;\r\n\r\n                    if (event.getTransition() == null) return;\r\n\r\n                    ReplicationState dest = event.getTransition().getDestination();\r\n\r\n                    final int replicationProgress =\r\n                            ((dest == ReplicationState.STOPPING ||\r\n                              dest == ReplicationState.STOPPED) ?\r\n                                    View.INVISIBLE : View.VISIBLE);\r\n\r\n                    runOnUiThread(new Runnable() {\r\n                        @Override\r\n                        public void run() {\r\n                            progressBar.setVisibility(replicationProgress);\r\n                        }\r\n                    });\r\n                }\r\n            }\r\n        );\r\n    }\r\n}<\/pre>\n<p>El n\u00facleo del c\u00f3digo consiste en dos escuchadores de cambios, uno para la base de datos y otro para las r\u00e9plicas. Cada interfaz de escucha define un \u00fanico m\u00e9todo <code>cambiado<\/code>.<\/p>\n<p>El receptor de cambios de documentos nos permite seguir las actualizaciones reales de los documentos. Una r\u00e9plica puede cambiar m\u00e1s 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\u00f1adimos 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\u00e1cilmente con la funci\u00f3n <code>runOnUiThread<\/code> de la Actividad.<\/p>\n<p>El otro listener nos permite mostrar un spinner de ocupado-espera (barra de progreso indefinida) dependiendo del estado de Replicaci\u00f3n. Puede leer m\u00e1s sobre la monitorizaci\u00f3n del estado de replicaci\u00f3n <a href=\"https:\/\/www.couchbase.com\/blog\/es\/determining-status-replication-couchbase-lite\/\">aqu\u00ed<\/a>.<\/p>\n<h3>La clase auxiliar de base de datos<\/h3>\n<p>A menudo envuelvo funciones de base de datos en una clase helper. Como s\u00f3lo necesitamos una instancia del helper, utilizo un patr\u00f3n singleton. Al igual que UA, quiero que el helper est\u00e9 disponible antes de que se inicie la aplicaci\u00f3n principal. Utilizo la misma t\u00e9cnica de poner el c\u00f3digo en un Content Provider.<\/p>\n<p>Aqu\u00ed est\u00e1 el listado completo de CBLHelper.java.<\/p>\n<pre class=\"lang:java decode:true\">package com.couchbase.cblite.android.cbpushsync;\r\n\r\nimport android.content.ContentProvider;\r\nimport android.content.ContentValues;\r\nimport android.database.Cursor;\r\nimport android.net.Uri;\r\nimport android.os.Handler;\r\nimport android.os.Looper;\r\nimport android.support.annotation.NonNull;\r\nimport android.support.annotation.Nullable;\r\nimport android.util.Log;\r\n\r\nimport com.couchbase.lite.CouchbaseLiteException;\r\nimport com.couchbase.lite.Database;\r\nimport com.couchbase.lite.Document;\r\nimport com.couchbase.lite.Manager;\r\nimport com.couchbase.lite.android.AndroidContext;\r\nimport com.couchbase.lite.replicator.Replication;\r\n\r\nimport java.io.IOException;\r\nimport java.net.URL;\r\n\r\npublic class CBLHelper extends ContentProvider {\r\n    public static final String TAG = \"Push Sync\";\r\n\r\n    private static String DB = \"db\";\r\n    \/\/private static String syncGateway = \"https:\/\/localhost:4984\";\r\n    private static String syncGateway = \"https:\/\/10.0.2.2:4984\";\r\n    private static URL syncGatewayURL;\r\n\r\n    private Manager manager;\r\n    private Database database;\r\n    private Replication puller;\r\n\r\n    private Database.ChangeListener databaseChangeListener;\r\n    private Replication.ChangeListener replicationChangeListener;\r\n\r\n    private static CBLHelper instance;\r\n\r\n    public static CBLHelper getInstance() { return instance; }\r\n\r\n    @Override\r\n    public boolean onCreate() {\r\n        instance = this;\r\n\r\n        enableLogging();\r\n\r\n        try {\r\n            syncGatewayURL = new URL(syncGateway + \"\/\" + DB);\r\n            manager = new Manager(new AndroidContext(getContext()), Manager.DEFAULT_OPTIONS);\r\n        } catch (IOException ex) {\r\n            ex.printStackTrace();\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    public void closeDatabase() {\r\n        database.close();\r\n    }\r\n\r\n    public void startReplication() {\r\n        puller.start();\r\n    }\r\n\r\n    public void stopReplication() { puller.stop(); }\r\n\r\n    public void reset() {\r\n        stopReplication();\r\n\r\n        try {\r\n            database.delete();\r\n        } catch (CouchbaseLiteException ex) {\r\n            ex.printStackTrace();\r\n        }\r\n\r\n        initialize(databaseChangeListener, replicationChangeListener);\r\n    }\r\n\r\n    public void initialize(Database.ChangeListener dbl, Replication.ChangeListener rl) {\r\n        try {\r\n            database = manager.getDatabase(DB);\r\n        } catch (CouchbaseLiteException ex) {\r\n            ex.printStackTrace();\r\n        }\r\n\r\n        database.addChangeListener(dbl);\r\n        databaseChangeListener = dbl;\r\n\r\n        puller = database.createPullReplication(syncGatewayURL);\r\n        puller.addChangeListener(rl);\r\n        replicationChangeListener = rl;\r\n    }\r\n\r\n    public Document getExistingDocument(String documentID) {\r\n        return database.getExistingDocument(documentID);\r\n    }\r\n\r\n    \/\/ Logging\r\n\r\n    private void enableLogging() {\r\n        Manager.enableLogging(TAG, Log.VERBOSE);\r\n        Manager.enableLogging(com.couchbase.lite.util.Log.TAG, Log.VERBOSE);\r\n        Manager.enableLogging(com.couchbase.lite.util.Log.TAG_SYNC_ASYNC_TASK, Log.VERBOSE);\r\n        Manager.enableLogging(com.couchbase.lite.util.Log.TAG_SYNC, Log.VERBOSE);\r\n        Manager.enableLogging(com.couchbase.lite.util.Log.TAG_QUERY, Log.VERBOSE);\r\n        Manager.enableLogging(com.couchbase.lite.util.Log.TAG_VIEW, Log.VERBOSE);\r\n        Manager.enableLogging(com.couchbase.lite.util.Log.TAG_DATABASE, Log.VERBOSE);\r\n    }\r\n\r\n    \/\/ Helper function to dispatch on UI thread\r\n    private void runOnUiThread(Runnable runnable) {\r\n        new Handler(Looper.getMainLooper()).post(runnable);\r\n    }\r\n\r\n    \/\/ Required overrides\r\n\r\n    @Nullable\r\n    @Override\r\n    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {\r\n        return null;\r\n    }\r\n\r\n    @Nullable\r\n    @Override\r\n    public String getType(@NonNull Uri uri) {\r\n        return null;\r\n    }\r\n\r\n    @Nullable\r\n    @Override\r\n    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {\r\n        return null;\r\n    }\r\n\r\n    @Override\r\n    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {\r\n        return 0;\r\n    }\r\n\r\n    @Override\r\n    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {\r\n        return 0;\r\n    }\r\n}\r\n<\/pre>\n<p>Puedes ver que esta clase s\u00f3lo forma una fina envoltura. Retenemos una instancia de la clase durante <code>onCreate<\/code> que se convierte en nuestro singleton. Algunas otras configuraciones b\u00e1sicas ocurren, como habilitar el registro y crear un gestor de base de datos. Escrib\u00ed un <code>inicializar<\/code> utilizado para abrir la base de datos, preparar la replicaci\u00f3n pull y adjuntar los dos escuchadores de cambios. Recuerde que esto es llamado desde nuestra clase Activity. (Nota: Puedes tener m\u00e1s de un receptor de cambios para cada tipo. Couchbase mantiene una lista de todos los escuchadores a\u00f1adidos, no s\u00f3lo del \u00faltimo). Los otros m\u00e9todos de la base de datos s\u00f3lo proporcionan atajos simples.<\/p>\n<p>Un proveedor de contenidos tiene varios m\u00e9todos obligatorios que implementar. Tenemos que proporcionar stubs para ellos, que se ven en los \u00faltimos cinco m\u00e9todos.<\/p>\n<h2>El manifiesto de Android<\/h2>\n<p>Por \u00faltimo, s\u00f3lo para mostrar c\u00f3mo esto se une y las diversas partes se exponen, he incluido el archivo de manifiesto de Android para el proyecto.<\/p>\n<p>Aqu\u00ed est\u00e1 el listado completo de AndroidManifest.xml.<\/p>\n<pre class=\"lang:default decode:true\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\r\n&lt;manifest xmlns:android=\"https:\/\/schemas.android.com\/apk\/res\/android\"\r\n    package=\"com.couchbase.cblite.android.cbpushsync\"&gt;\r\n\r\n    &lt;application\r\n        android:allowBackup=\"true\"\r\n        android:icon=\"@mipmap\/ic_launcher\"\r\n        android:label=\"@string\/app_name\"\r\n        android:supportsRtl=\"true\"\r\n        android:theme=\"@style\/AppTheme\"&gt;\r\n        &lt;meta-data android:name=\"com.urbanairship.autopilot\"\r\n            android:value=\"com.couchbase.cblite.android.cbpushsync.CBAutoPilot\"\/&gt;\r\n        &lt;activity\r\n            android:name=\".MainActivity\"\r\n            android:label=\"@string\/app_name\"\r\n            android:theme=\"@style\/AppTheme.NoActionBar\"&gt;\r\n            &lt;intent-filter&gt;\r\n                &lt;action android:name=\"android.intent.action.MAIN\" \/&gt;\r\n\r\n                &lt;category android:name=\"android.intent.category.LAUNCHER\" \/&gt;\r\n            &lt;\/intent-filter&gt;\r\n        &lt;\/activity&gt;\r\n        &lt;receiver android:name=\".CBAirshipReceiver\"\r\n            android:exported=\"false\"&gt;\r\n\r\n            &lt;intent-filter&gt;\r\n                &lt;action android:name=\"com.urbanairship.push.CHANNEL_UPDATED\" \/&gt;\r\n                &lt;action android:name=\"com.urbanairship.push.OPENED\" \/&gt;\r\n                &lt;action android:name=\"com.urbanairship.push.RECEIVED\" \/&gt;\r\n                &lt;action android:name=\"com.urbanairship.push.DISMISSED\" \/&gt;\r\n\r\n                &lt;category android:name=\"${applicationId}\" \/&gt;\r\n            &lt;\/intent-filter&gt;\r\n        &lt;\/receiver&gt;\r\n        &lt;provider\r\n            android:authorities=\"${applicationId}.dbhelper\"\r\n            android:exported=\"false\"\r\n            android:enabled=\"true\"\r\n            android:name=\".CBLHelper\" \/&gt;\r\n    &lt;\/application&gt;\r\n\r\n&lt;\/manifest&gt;<\/pre>\n<p>La biblioteca UA viene con su propio archivo de manifiesto. El sistema de compilaci\u00f3n 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\u00e1s las entradas para el proveedor de contenido que arranca la biblioteca.<\/p>\n<h2>Pasarela de sincronizaci\u00f3n<\/h2>\n<p>Para probar la aplicaci\u00f3n, utilic\u00e9 Sync Gateway con la base de datos integrada Walrus. Walrus es una <a href=\"https:\/\/www.couchbase.com\/blog\/es\/resources\/concepts\/in-memory-database\/\">base de datos en memoria<\/a> normalmente se utiliza s\u00f3lo para pruebas. Esto ahorra la molestia de configurar una instancia back-end de Couchbase Server.<\/p>\n<p>Aqu\u00ed est\u00e1 la lista completa del archivo de configuraci\u00f3n de Sync Gateway.<\/p>\n<pre class=\"lang:default decode:true\">{\r\n  \"log\": [\"HTTP+\"],\r\n  \"adminInterface\": \"127.0.0.1:4985\",\r\n  \"interface\": \"127.0.0.1:4984\",\r\n  \"CORS\": {\r\n    \"origin\":[\"*\"],\r\n    \"loginorigin\":[\"*\"],\r\n    \"headers\":[\"Content-Type\"],\r\n    \"maxAge\": 1728000\r\n  },\r\n  \"databases\": {\r\n    \"db\": {\r\n      \"server\": \"walrus:\",\r\n      \"users\": { \"GUEST\": {\"disabled\": false, \"admin_channels\": [\"*\"] } }\r\n    }\r\n  }\r\n}<\/pre>\n<p>Esto le dice a Sync Gateway para escuchar s\u00f3lo en el <code>localhost<\/code> aceptar cualquier petici\u00f3n de origen cruzado, y habilita el GUEST especial con acceso a todos los canales. Es una muy buena configuraci\u00f3n de prop\u00f3sito general para empezar a asegurarse de que todo est\u00e1 funcionando.<\/p>\n<p>Usted puede haber notado que usamos 10.0.2.2 como la direcci\u00f3n IP para Sync Gateway en la aplicaci\u00f3n Android. El emulador est\u00e1ndar que viene con Android Studio asigna esto autom\u00e1ticamente a la m\u00e1quina de alojamiento de <code>localhost<\/code>. Si utilizas un emulador diferente (Genymotion es otro de los m\u00e1s populares), aseg\u00farate de buscar qu\u00e9 direcci\u00f3n IP utilizar, ya que difieren.<\/p>\n<p>Si desea obtener m\u00e1s informaci\u00f3n acerca de la configuraci\u00f3n de Sync Gateway en su equipo de desarrollo, o c\u00f3mo trabajar con \u00e9l desde la l\u00ednea de comandos, eche un vistazo a esto <a href=\"https:\/\/www.couchbase.com\/blog\/es\/getting-comfortable-couchbase-mobile-installing-sync-gateway\/\">serie de blogs<\/a>.<\/p>\n<h2>Pruebas<\/h2>\n<p>Para probarlo todo y grabar la animaci\u00f3n que se muestra al principio del blog, ejecuto tanto el emulador de Android como Sync Gateway en una misma m\u00e1quina. A continuaci\u00f3n, env\u00edo notificaciones push a UA a trav\u00e9s de su API REST.<\/p>\n<p>Para preparar algo interesante, primero a\u00f1ado un documento a Sync Gateway. He aqu\u00ed un comando shell para hacerlo.<\/p>\n<pre class=\"lang:sh decode:true\">$ curl -X PUT -H 'Content-Type: application\/json' -H 'Accept: application\/json' -d '{ \"test\" : \"UA\", \"channels\": \"public\" }' https:\/\/localhost:4984\/db\/doc\r\n<\/pre>\n<p>(M\u00e1s informaci\u00f3n <a href=\"https:\/\/www.couchbase.com\/blog\/es\/getting-comfortable-with-couchbase-mobile-sync-gateway-via-the-command-line\/\">aqu\u00ed<\/a>).<\/p>\n<p>Con un nuevo documento en la base de datos de Sync Gateway y la aplicaci\u00f3n en funcionamiento, s\u00f3lo queda activar una replicaci\u00f3n pull para ver la acci\u00f3n.<\/p>\n<p>Aqu\u00ed est\u00e1 el <code>rizo<\/code> para enviar una se\u00f1al de \"inicio\". Recordemos que extraigo el valor de la parte \"alerta\" de la notificaci\u00f3n para desencadenar acciones.<\/p>\n<pre class=\"lang:sh decode:true\">$ curl https:\/\/go.urbanairship.com\/api\/push -u 'appKey:appMasterSecret' -X POST -H 'Content-Type: application\/json' -H 'Accept: application\/vnd.urbanairship+json; version=3;' -d '{ \"audience\": { \"android_channel\": \"3110bc81-1c7b-4ef8-a7a3-7c56aab19f08\" }, \"notification\" : { \"alert\": \"start\" }, \"device_types\": \"all\" }'<\/pre>\n<p>Tendr\u00e1s que proporcionar tu propia clave de aplicaci\u00f3n y el secreto maestro de la aplicaci\u00f3n anterior. Tambi\u00e9n 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\u00fan efecto, comprueba el valor del canal.<\/p>\n<p>Despu\u00e9s de publicar en UA, deber\u00edas ver una respuesta como esta.<\/p>\n<pre class=\"lang:default decode:true\">{\"ok\":true,\"operation_id\":\"2a6c0edf-e5d0-4b4d-b762-ad5c4478c291\",\"push_ids\":[\"1951019a-2b7f-4f1b-8888-e87047a1feec\"],\"message_ids\":[],\"content_urls\":[]}<\/pre>\n<p>Y, por \u00faltimo, para restablecer una base de datos en blanco y volver a intentarlo, puedes publicar esto.<\/p>\n<pre class=\"lang:sh decode:true\">$ curl https:\/\/go.urbanairship.com\/api\/push -u 'appKey:appMasterSecret' -X POST -H 'Content-Type: application\/json' -H 'Accept: application\/vnd.urbanairship+json; version=3;' -d '{ \"audience\": { \"android_channel\": \"3110bc81-1c7b-4ef8-a7a3-7c56aab19f08\" }, \"notification\" : { \"alert\": \"reset\" }, \"device_types\": \"all\" }'\r\n<\/pre>\n<h2>Conclusi\u00f3n<\/h2>\n<p>Esto es todo para preparar nuestra aplicaci\u00f3n Android para realizar r\u00e9plicas basadas en notificaciones push. Aseg\u00farese de revisar <a href=\"https:\/\/www.couchbase.com\/blog\/es\/node-js-swagger-monitor-document-changes-couchbase-mobile\/\">esta entrada<\/a> sobre la supervisi\u00f3n de la fuente de cambios de Sync Gateway.<\/p>\n<h2>Posdata<\/h2>\n<p>Descargar Couchbase y Sync Gateway <a href=\"https:\/\/www.couchbase.com\/blog\/es\/downloads\/\">aqu\u00ed<\/a>. Consulte nuestro <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/current\/guides\/couchbase-lite\/index.html?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">documentaci\u00f3n<\/a> para saber c\u00f3mo a\u00f1adir Couchbase Lite a un proyecto.<\/p>\n<p>Consulte m\u00e1s recursos en nuestra <a href=\"https:\/\/www.couchbase.com\/blog\/es\/developers\/community\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">portal para desarrolladores<\/a> y s\u00edganos en Twitter <a href=\"https:\/\/twitter.com\/CouchbaseDev\">@CouchbaseDev<\/a>.<\/p>\n<p>Puede enviar preguntas a nuestro <a href=\"https:\/\/www.couchbase.com\/blog\/es\/forums\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">foros<\/a>. Y participamos activamente en <a href=\"https:\/\/stackoverflow.com\/questions\/tagged\/couchbase\">Stack Overflow<\/a>.<\/p>\n<p>Env\u00edame tus preguntas, comentarios, temas que te gustar\u00eda ver, etc. a Twitter. <a href=\"https:\/\/twitter.com\/HodGreeley\">@HodGreeley<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Urban Airship is a popular messaging and notification service. \u00a0In part 1 of this post we&#8217;ll look at how to set up Urban Airship push notifications. In part 2 of the post we\u2019ll use these notifications to trigger replications in [&hellip;]<\/p>","protected":false},"author":73,"featured_media":10144,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1810],"tags":[],"ppma_author":[9042],"class_list":["post-2515","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-mobile"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.2 (Yoast SEO v26.2) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Urban Airship Push Notifications: What You Need to Start<\/title>\n<meta name=\"description\" content=\"Look at this blog post to see how to set up Urban Airship push notifications and how to use these notifications to trigger replications in Couchbase Mobile.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/es\/getting-started-with-urban-airship-push-notifications\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Getting Started with Urban Airship Push Notifications\" \/>\n<meta property=\"og:description\" content=\"Look at this blog post to see how to set up Urban Airship push notifications and how to use these notifications to trigger replications in Couchbase Mobile.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/getting-started-with-urban-airship-push-notifications\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-04-23T23:14:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-12T20:26:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/04\/big-data-2001190_1280.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"720\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Hod Greeley, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@HodGreeley\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hod Greeley, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/\"},\"author\":{\"name\":\"Hod Greeley, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4\"},\"headline\":\"Getting Started with Urban Airship Push Notifications\",\"datePublished\":\"2017-04-23T23:14:25+00:00\",\"dateModified\":\"2024-01-12T20:26:11+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/\"},\"wordCount\":2410,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/04\/big-data-2001190_1280.jpg\",\"articleSection\":[\"Couchbase Mobile\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/\",\"name\":\"Urban Airship Push Notifications: What You Need to Start\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/04\/big-data-2001190_1280.jpg\",\"datePublished\":\"2017-04-23T23:14:25+00:00\",\"dateModified\":\"2024-01-12T20:26:11+00:00\",\"description\":\"Look at this blog post to see how to set up Urban Airship push notifications and how to use these notifications to trigger replications in Couchbase Mobile.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/04\/big-data-2001190_1280.jpg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/04\/big-data-2001190_1280.jpg\",\"width\":1280,\"height\":720,\"caption\":\"Urban Airship with Couchbase\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Getting Started with Urban Airship Push Notifications\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4\",\"name\":\"Hod Greeley, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/21eb69cb5d4a401fb23b149e4f4e9e87\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g\",\"caption\":\"Hod Greeley, Developer Advocate, Couchbase\"},\"description\":\"Hod Greeley is a Developer Advocate for Couchbase, living in Silicon Valley. He has over two decades of experience as a software engineer and engineering manager. He has worked in a variety of software fields, including computational physics and chemistry, computer and network security, finance, and mobile. Prior to joining Couchbase in 2016, Hod led developer relations for mobile at Samsung. Hod holds a Ph.D. in chemical physics from Columbia University.\",\"sameAs\":[\"https:\/\/hod.greeley.org\/blog\",\"https:\/\/x.com\/HodGreeley\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/hod-greeley\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Urban Airship Push Notifications: What You Need to Start","description":"Look at this blog post to see how to set up Urban Airship push notifications and how to use these notifications to trigger replications in Couchbase Mobile.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/es\/getting-started-with-urban-airship-push-notifications\/","og_locale":"es_MX","og_type":"article","og_title":"Getting Started with Urban Airship Push Notifications","og_description":"Look at this blog post to see how to set up Urban Airship push notifications and how to use these notifications to trigger replications in Couchbase Mobile.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/getting-started-with-urban-airship-push-notifications\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-04-23T23:14:25+00:00","article_modified_time":"2024-01-12T20:26:11+00:00","og_image":[{"width":1280,"height":720,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/04\/big-data-2001190_1280.jpg","type":"image\/jpeg"}],"author":"Hod Greeley, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@HodGreeley","twitter_misc":{"Written by":"Hod Greeley, Developer Advocate, Couchbase","Est. reading time":"12 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/"},"author":{"name":"Hod Greeley, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4"},"headline":"Getting Started with Urban Airship Push Notifications","datePublished":"2017-04-23T23:14:25+00:00","dateModified":"2024-01-12T20:26:11+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/"},"wordCount":2410,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/04\/big-data-2001190_1280.jpg","articleSection":["Couchbase Mobile"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/","url":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/","name":"Urban Airship Push Notifications: What You Need to Start","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/04\/big-data-2001190_1280.jpg","datePublished":"2017-04-23T23:14:25+00:00","dateModified":"2024-01-12T20:26:11+00:00","description":"Look at this blog post to see how to set up Urban Airship push notifications and how to use these notifications to trigger replications in Couchbase Mobile.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/04\/big-data-2001190_1280.jpg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/04\/big-data-2001190_1280.jpg","width":1280,"height":720,"caption":"Urban Airship with Couchbase"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/getting-started-with-urban-airship-push-notifications\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Getting Started with Urban Airship Push Notifications"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4","name":"Hod Greeley, Defensor del Desarrollador, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/21eb69cb5d4a401fb23b149e4f4e9e87","url":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","caption":"Hod Greeley, Developer Advocate, Couchbase"},"description":"Hod Greeley es desarrollador de Couchbase y vive en Silicon Valley. Tiene m\u00e1s de dos d\u00e9cadas de experiencia como ingeniero de software y director de ingenier\u00eda. Ha trabajado en una variedad de campos de software, incluyendo f\u00edsica computacional y qu\u00edmica, seguridad inform\u00e1tica y de redes, finanzas y m\u00f3viles. Antes de unirse a Couchbase en 2016, Hod dirigi\u00f3 las relaciones con desarrolladores para m\u00f3viles en Samsung. Hod es doctor en f\u00edsica qu\u00edmica por la Universidad de Columbia.","sameAs":["https:\/\/hod.greeley.org\/blog","https:\/\/x.com\/HodGreeley"],"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/hod-greeley\/"}]}},"authors":[{"term_id":9042,"user_id":73,"is_guest":0,"slug":"hod-greeley","display_name":"Hod Greeley, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","author_category":"","last_name":"Greeley","first_name":"Hod","job_title":"","user_url":"https:\/\/hod.greeley.org\/blog","description":"Hod Greeley es desarrollador de Couchbase y vive en Silicon Valley. Tiene m\u00e1s de dos d\u00e9cadas de experiencia como ingeniero de software y director de ingenier\u00eda. Ha trabajado en una variedad de campos de software, incluyendo f\u00edsica computacional y qu\u00edmica, seguridad inform\u00e1tica y de redes, finanzas y m\u00f3viles. Antes de unirse a Couchbase en 2016, Hod dirigi\u00f3 las relaciones con desarrolladores para m\u00f3viles en Samsung. Hod es doctor en f\u00edsica qu\u00edmica por la Universidad de Columbia."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2515","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/73"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=2515"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2515\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/10144"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=2515"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2515"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2515"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2515"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}