{"id":1971,"date":"2015-12-16T01:00:02","date_gmt":"2015-12-16T01:00:01","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1971"},"modified":"2019-03-04T06:21:10","modified_gmt":"2019-03-04T14:21:10","slug":"couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/","title":{"rendered":"Couchbase Mobile: Modificaci\u00f3n del acceso de lectura en la funci\u00f3n de sincronizaci\u00f3n y replicaci\u00f3n de los cambios en una aplicaci\u00f3n Android"},"content":{"rendered":"<p>Con nuevas herramientas como Android Public Beta Testing y Testflight para iOS, enviar nuevas actualizaciones de una aplicaci\u00f3n m\u00f3vil nativa con mayor regularidad es una tendencia creciente.<\/p>\n<p>Adem\u00e1s de cambiar la l\u00f3gica empresarial y los modelos de datos con mayor regularidad, tambi\u00e9n es necesario dar soporte a las versiones anteriores. A diferencia de un sitio web, en el que el usuario siempre accede a la \u00faltima versi\u00f3n desde el navegador, las aplicaciones m\u00f3viles pueden permanecer en el dispositivo de un usuario durante un largo periodo de tiempo sin actualizarse.<\/p>\n<p>En este tutorial, aprender\u00e1s c\u00f3mo enviar una actualizaci\u00f3n a tu aplicaci\u00f3n Android con Couchbase Mobile. Utilizar\u00e1s un webhook de Sync Gateway para importar datos de una API de terceros bajo demanda (en este caso la API de Google Places) con Node.js. En la primera instancia, la aplicaci\u00f3n Android sincronizar\u00e1 todos los datos y en una versi\u00f3n posterior de la aplicaci\u00f3n, s\u00f3lo extraer\u00e1 un subconjunto de ellos. Al cambiar las reglas de acceso en la funci\u00f3n de sincronizaci\u00f3n, utilizar\u00e1 la pasarela de sincronizaci\u00f3n <strong>resincronizar<\/strong> para reconstruir las reglas de acceso de acuerdo con la funci\u00f3n de sincronizaci\u00f3n actualizada.<\/p>\n<p>Empecemos.<\/p>\n<p>El orden en el que reunir\u00e1s los distintos componentes es el siguiente:<\/p>\n<ol>\n<li>Instalaci\u00f3n de Sync Gateway<\/li>\n<li>Configuraci\u00f3n del Webhook<\/li>\n<li>Creaci\u00f3n del servidor de aplicaciones<\/li>\n<li>Creaci\u00f3n de la aplicaci\u00f3n Android<\/li>\n<\/ol>\n<h2>Primeros pasos<\/h2>\n<p>Descargue Sync Gateway y descomprima el archivo:<\/p>\n<p>https:\/\/www.couchbase.com\/nosql-databases\/downloads#Couchbase_Mobile<\/p>\n<p>Puede encontrar el binario de Sync Gateway en la carpeta <strong>papelera<\/strong> y ejemplos de archivos de configuraci\u00f3n en la carpeta <strong>ejemplos<\/strong> carpeta. Copie la carpeta <strong>basic-walrus-bucket.json<\/strong> en la ra\u00edz del proyecto:<\/p>\n<pre><code class=\"language-none\">$ cp \/Downloads\/couchbase-sync-gateway\/examples\/basic-walrus-bucket.json \/path\/to\/proj\/sync-gateway-config.json<\/code><\/pre>\n<p>Inicie Sync Gateway:<\/p>\n<pre><code class=\"language-none\">$ ~\/Downloads\/couchbase-sync-gateway\/bin\/sync_gateway<\/code><\/pre>\n<h2>Webhook de la pasarela de sincronizaci\u00f3n<\/h2>\n<p>El webhook se define en el archivo de configuraci\u00f3n que cre\u00f3 anteriormente y toma un archivo <strong>url<\/strong> para POST y un <strong>funci\u00f3n de filtro<\/strong> (opcional). A\u00f1ada el <strong>manejadores de eventos<\/strong> campo en <strong>sync-gateway-config.json<\/strong> con las siguientes propiedades:<\/p>\n<pre><code class=\"language-javascript\">{\r\n  \"log\": [\"*\"],\r\n  \"databases\": {\r\n    \"db\": {\r\n      \"bucket\": \"default\",\r\n      \"server\": \"https:\/\/localhost:8091\",\r\n      \"users\": { \"GUEST\": { \"disabled\": false, \"admin_channels\": [\"*\"] } },\r\n      \"event_handlers\": {\r\n        \"document_changed\": [\r\n          {\r\n            \"handler\": \"webhook\",\r\n            \"url\": \"https:\/\/localhost:8000\/sync_request\",\r\n            \"filter\": `function(doc) {\r\n              if (doc.type == \"profile\") {\r\n                return true;\r\n              }\r\n              return false;\r\n            }`\r\n          }\r\n        ]\r\n      }\r\n    }\r\n  }\r\n}<\/code><\/pre>\n<p>He aqu\u00ed lo que hace cada nuevo campo:<\/p>\n<ul>\n<li><strong>manipulador<\/strong>: Est\u00e1 especificando que el tipo de evento sea <strong>webhook<\/strong><\/li>\n<li><strong>url<\/strong>: La url a la que enviar la petici\u00f3n POST con el documento en el cuerpo del mensaje.<\/li>\n<li><strong>filtro<\/strong>: Una funci\u00f3n escrita en JavaScript para activar el webhook s\u00f3lo si devuelve <strong>verdadero<\/strong>. Tenga en cuenta que el webhook s\u00f3lo se ejecutar\u00e1 si el documento tiene una etiqueta <strong>tipo<\/strong> igual a <strong>perfil<\/strong><\/li>\n<\/ul>\n<p>Guarde los cambios y reinicie Sync Gateway:<\/p>\n<pre><code class=\"language-bash\">$ ~\/Downloads\/couchbase-sync-gateway\/bin\/sync_gateway .\/sync-gateway-config.json<\/code><\/pre>\n<h2>Servidor de aplicaciones<\/h2>\n<p>En esta secci\u00f3n, utilizar\u00e1s Node.js y el framework Express para configurar un App Server que gestione el webhook. En el mismo directorio, instala los m\u00f3dulos de Node.js necesarios:<\/p>\n<pre><code class=\"language-bash\">npm install express body-parser --save<\/code><\/pre>\n<p>En un nuevo archivo llamado <strong>servidor.js<\/strong> a\u00f1ada el siguiente c\u00f3digo:<\/p>\n<pre><code class=\"language-javascript\">var express = require('express');\r\nvar bodyParser = require('body-parser');\r\nvar app = express();\r\napp.use(bodyParser.json());\r\n\r\n\/**\r\n * Handle the Sync Gateway webhook request.\r\n * The request body contains the document.\r\n *\/\r\napp.post('\/sync_request', function (req, res) {\r\n  var document = req.body;\r\n  console.log('Handle webhook with doc :: %s', JSON.stringify(document));\r\n  res.sendStatus(200);\r\n});\r\n\r\nvar server = app.listen(8000, function () {\r\n  var host = server.address().address;\r\n  var port = server.address().port;\r\n\r\n  console.log('App listening at https:\/\/%s:%s', host, port);\r\n});<\/code><\/pre>\n<p>Inicie el servidor de aplicaciones Node.js ejecutando <strong>node servidor.js<\/strong> y guarde un documento en Sync Gateway utilizando la API REST para asegurarse de que el webhook funciona:<\/p>\n<pre><code class=\"language-bash\">$ curl -vX POST :4984\/db\/ \r\n        -H 'Content-Type: application\/json' \r\n        -d '{\"type\": \"profile\", \"name\": \"james\"}'<\/code><\/pre>\n<p>Deber\u00eda ver la siguiente salida en los registros del App Server:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/test_webhook.png\" \/><\/p>\n<p>\u00a1Magn\u00edfico! El webhook est\u00e1 funcionando. A continuaci\u00f3n, va a a\u00f1adir algo de c\u00f3digo para importar los datos JSON de la API de Lugares en Sync Gateway. Para ello, utilizar\u00e1 RxJS y Request. El c\u00f3digo que maneja m\u00e1s de un evento o c\u00e1lculo as\u00edncrono se complica r\u00e1pidamente. RxJS realiza estos c\u00e1lculos <em>ciudadanos de primera clase<\/em> y proporciona un modelo que permite APIs legibles y componibles. Y el m\u00f3dulo Request es la librer\u00eda de-facto para hacer las peticiones http en NodeJS m\u00e1s simples que nunca. En el mismo directorio, instala las dependencias:<\/p>\n<pre><code class=\"language-bash\">$ npm install request rx --save<\/code><\/pre>\n<p>Copia <strong>requestRx.js<\/strong> de este <a href=\"https:\/\/github.com\/couchbaselabs\/mini-hacks\/tree\/master\/sync-gateway-resync-android\">Repo de GitHub<\/a> en la carpeta del proyecto. Simplemente estamos envolviendo la API Request en construcciones RxJS (flatMap, filter, subscribe...). Por ejemplo, en lugar de utilizar <code>solicitar.obtener<\/code>utilizar\u00e1s <code>requestRx.get<\/code>.<\/p>\n<p>Abra un nuevo archivo llamado <strong>sync.js<\/strong>requieren el <strong>requestRx<\/strong> y <strong>Rx<\/strong> y a\u00f1ada el siguiente c\u00f3digo:<\/p>\n<pre><code class=\"language-javascript\">var requestRx = require('.\/requestRx.js');\r\nvar Rx = require('rx');\r\n\r\nconst api_key = 'AIzaSyD4e6ZUIc9G2AxKansIUKa0enFzWZy5h8w';\r\nconst url = 'https:\/\/maps.googleapis.com\/maps\/api\/place';\r\nconst gateway = 'https:\/\/localhost:4985\/db';\r\n\r\nvar SyncRequest = {\r\n  syncRequest: function(city) {\r\n    console.log('city to sync with %s', city);\r\n    \/\/ 1. Search for Places\r\n    requestRx.get(`${url}\/textsearch\/json?key=${api_key}&amp;query=restaurants+in+${city}`)\r\n      .subscribe((res) =&gt; {\r\n        var places = JSON.parse(res.body).results;\r\n        places = places.map(function (place) {\r\n          place.city = city;\r\n          place._id = place.place_id;\r\n          delete place.place_id;\r\n          return place;\r\n        });\r\n        var placesStream = Rx.Observable.fromArray(places);\r\n\r\n        \/\/ 2. Send the Places in bulk to Sync Gateway\r\n        requestRx({uri: `${gateway}\/_bulk_docs`, method: 'POST', json: {docs: places}})\r\n          .flatMap((docsRes) =&gt; {\r\n            var docsStream = Rx.Observable.fromArray(docsRes.body);\r\n\r\n            \/\/ Merge the place's photoreference with the doc id and rev\r\n            return Rx.Observable.zip(placesStream, docsStream, (place, doc) =&gt; {\r\n              return {\r\n                id: doc.id,\r\n                rev: doc.rev,\r\n                ref: place.photos ? place.photos[0].photo_reference : 'CmRdAAAAA6MaWi5PIUhFumEYbHiM8IWHhJJvw1ss11QH1prE_x0PnUgyiyIiQmSNvfMu1lztLAA0mNdZa5Mr32ho5hE5nOKDAdOfVKcw4kLe0LKdDoYFENmRR1FE4AosTUhBvNCvEhB5HYf69MG389U27lkhrcPqGhSDbG7UhU9buWSEn2DRpy8E_R3oAg'\r\n              }\r\n            });\r\n          })\r\n          .flatMap((doc) =&gt; {\r\n\r\n            \/\/ 3. Get the binary jpg photo using the ref property (i.e. photoreference)\r\n            var options = {\r\n              uri: `${url}\/photo?key=${api_key}&amp;maxwidth=400&amp;photoreference=${doc.ref}`,\r\n              encoding: null\r\n            };\r\n            return requestRx.get(options)\r\n              .flatMap((photo) =&gt; {\r\n\r\n                \/\/ 4. Save the photo as an attachment on the corresponding document\r\n                return requestRx({\r\n                  uri: `${gateway}\/${doc.id}\/photo?rev=${doc.rev}`,\r\n                  method: 'PUT',\r\n                  headers: {'Content-Type': 'image\/jpg'},\r\n                  body: photo.body\r\n                })\r\n              })\r\n          })\r\n          .subscribe((res) =&gt; {\r\n          });\r\n      });\r\n  }\r\n};\r\n\r\nmodule.exports = SyncRequest;<\/code><\/pre>\n<p>Esto es lo que ocurre paso a paso:<\/p>\n<ol>\n<li>Obtener los Lugares que coinciden con la consulta <strong>restaurantes en Londres<\/strong>. Utilice la funci\u00f3n de interpolaci\u00f3n de cadenas ES 6 en la url.<\/li>\n<li>En <strong><em>a granel<\/em>docs<\/strong> es muy pr\u00e1ctico para importar grandes conjuntos de datos a una instancia de Sync Gateway. Encontrar\u00e1 m\u00e1s informaci\u00f3n al respecto en <a href=\"https:\/\/developer.couchbase.com\/mobile\/develop\/references\/sync-gateway\/rest-api\/database\/post-bulk-docs\/index.html\">docs<\/a>.<\/li>\n<li>Despu\u00e9s de guardar el documento, guardas la foto como un archivo adjunto, primero debes obtener la imagen de la API de Lugares. F\u00edjate en el icono <strong>codificaci\u00f3n<\/strong> se establece en <strong>null<\/strong>. Esto es requerido por el m\u00f3dulo Request para cualquier cuerpo de respuesta que no sea una cadena. M\u00e1s informaci\u00f3n en la secci\u00f3n <a href=\"https:\/\/github.com\/request\/request#user-content-requestoptions-callback\">Solicitar documentos<\/a>.<\/li>\n<li>Debe indicar a Sync Gateway en qu\u00e9 documento (especificando el identificador del documento) y revisi\u00f3n de ese documento (especificando el n\u00famero de revisi\u00f3n) desea guardar este archivo adjunto.<\/li>\n<\/ol>\n<p>Observe que en la \u00faltima l\u00ednea est\u00e1 exportando el archivo <strong>SyncRequest<\/strong> objeto. En <strong>servidor.js<\/strong>requieren el <strong>sync.js<\/strong> y llamar al archivo <strong>syncRequest<\/strong> pasando en consecuencia el m\u00e9todo <strong>ciudad<\/strong> campo:<\/p>\n<pre><code class=\"language-javascript\">var express = require('express');\r\nvar bodyParser = require('body-parser');\r\nvar app = express();\r\napp.use(bodyParser.json());\r\n\r\nvar sync = require('.\/sync');\r\n\r\n\/**\r\n * Handle the Sync Gateway webhook request.\r\n * The request body contains the document.\r\n *\/\r\napp.post('\/sync_request', function (req, res) {\r\n  var document = req.body;\r\n  console.log('Handle webhook with doc :: %s', JSON.stringify(document));\r\n  sync.syncRequest(document.city);\r\n  res.sendStatus(200);\r\n});\r\n\r\nvar server = app.listen(8000, function () {\r\n  var host = server.address().address;\r\n  var port = server.address().port;\r\n\r\n  console.log('App listening at https:\/\/%s:%s', host, port);\r\n});<\/code><\/pre>\n<p>Habr\u00e1 observado que <strong>sync.js<\/strong> est\u00e1 escrito con la sintaxis ES6. Ejecutar <strong>node servidor.js<\/strong> no funcionar\u00e1 y deber\u00e1 instalar primero el <a href=\"https:\/\/babeljs.io\/\">Babel<\/a> globalmente:<\/p>\n<pre><code class=\"language-bash\">npm install babel-node -g<\/code><\/pre>\n<p>Ahora puede ejecutar el programa <strong>sync.js<\/strong> de forma independiente con el siguiente comando:<\/p>\n<pre><code class=\"language-bash\">babel-node -e \"require('.\/sync.js').syncRequest('London')\"<\/code><\/pre>\n<p>Abra el panel de administraci\u00f3n para supervisar los documentos guardados en Sync Gateway.<\/p>\n<p>https:\/\/localhost:4985\/_admin\/<\/p>\n<p>Ahora deber\u00eda ver 20 documentos en los que cada uno es un lugar de Londres:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/admin_ui_london_places.png\" \/><\/p>\n<h2>Creaci\u00f3n de la aplicaci\u00f3n Android<\/h2>\n<p>En esta secci\u00f3n, aprender\u00e1s a utilizar el SDK de Google Maps en Android para obtener la ciudad en la que se encuentra actualmente el usuario. Con esa informaci\u00f3n, crear\u00e1s un documento de tipo <strong>perfil<\/strong> para almacenar la ciudad actual.<\/p>\n<p>Abra Android Studio y seleccione <strong>Iniciar un nuevo proyecto de Android Studio<\/strong> del <strong>Inicio r\u00e1pido<\/strong> men\u00fa.<\/p>\n<p>Nombre de la aplicaci\u00f3n <strong>CityExplorer<\/strong>establezca un dominio de empresa y una ubicaci\u00f3n de proyecto adecuados y, a continuaci\u00f3n, haga clic en <strong>Siguiente<\/strong>:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/project_name.png\" \/><\/p>\n<p>En el cuadro de di\u00e1logo Dispositivos Android de destino, aseg\u00farese de marcar <strong>Tel\u00e9fono y tableta<\/strong>ajuste el SDK m\u00ednimo a <strong>API 22: Android 5.1 (Lollipop)<\/strong> para ambos, y haga clic en <strong>Siguiente<\/strong>:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/target_sdk.png\" \/><\/p>\n<p>En la siguiente <strong>A\u00f1adir una actividad a M\u00f3vil<\/strong> seleccione A\u00f1adir <strong>Actividad en blanco<\/strong> y nombre la actividad <strong>Actividad principal<\/strong>:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/main_activity.png\" \/><\/p>\n<p>Utilizar\u00e1 el <strong>proveedor de localizaci\u00f3n fusionado<\/strong> para recuperar la \u00faltima ubicaci\u00f3n conocida del dispositivo. En <strong>build.gradle<\/strong>a\u00f1ada la siguiente dependencia:<\/p>\n<pre><code class=\"language-groovy\">compile 'com.google.android.gms:play-services:7.5.0'<\/code><\/pre>\n<p>A\u00f1adir un permiso de solicitud de ubicaci\u00f3n en <strong>AndroidManifest.xml<\/strong> en el <strong>manifestar<\/strong> Etiqueta XML:<\/p>\n<pre><code class=\"language-xml\"><\/code><\/pre>\n<p>En <strong>MainActivity.java<\/strong>a\u00f1ade un nuevo m\u00e9todo llamado <strong>buildGoogleApiClient<\/strong> para inicializar el SDK de la API de Google y llamar al m\u00e9todo en <strong>onCreate<\/strong>:<\/p>\n<pre><code class=\"language-java\">protected synchronized void buildGoogleApiClient() {\r\n    mGoogleApiClient = new GoogleApiClient.Builder(this)\r\n            .addConnectionCallbacks(this)\r\n            .addOnConnectionFailedListener(this)\r\n            .addApi(LocationServices.API)\r\n            .build();\r\n    mGoogleApiClient.connect();\r\n}<\/code><\/pre>\n<p>A continuaci\u00f3n, har\u00e1 <strong>Actividad principal<\/strong> aplicar la <strong>GoogleApiClient.ConnectionCallbacks<\/strong> y <strong>GoogleApiClient.OnConnectionFailedListener<\/strong> y recuperar la ubicaci\u00f3n en <strong>onConnected<\/strong>:<\/p>\n<pre><code class=\"language-java\">@Override\r\npublic void onConnected(Bundle bundle) {\r\n    Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);\r\n    Geocoder geocoder = new Geocoder(this, Locale.getDefault());\r\n    List<\/code><\/pre>\n<address>addresses = null; try { addresses = geocoder.getFromLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude(), 1); } catch (IOException e) { e.printStackTrace(); } if (addresses.size() &gt; 0) { String city = addresses.get(0).getLocality(); cityLabel.setText(city); } } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { }<\/address>\n<pre><code class=\"language-java\"><\/code><\/pre>\n<p>Ejecute la aplicaci\u00f3n y deber\u00eda ver la ciudad actual en el centro de la pantalla:<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/android_location_screen.png\" \/><\/p>\n<p>A continuaci\u00f3n, a\u00f1adir\u00e1s Couchbase Lite a tu proyecto. En <strong>build.gradle<\/strong> a\u00f1ade lo siguiente:<\/p>\n<pre><code class=\"language-none\">\/\/ workaround for \"duplicate files during packaging of APK\" issue\r\n\/\/ see https:\/\/groups.google.com\/d\/msg\/adt-dev\/bl5Rc4Szpzg\/wC8cylTWuIEJ\r\npackagingOptions {\r\n    exclude 'META-INF\/ASL2.0'\r\n    exclude 'META-INF\/LICENSE'\r\n    exclude 'META-INF\/NOTICE'\r\n}<\/code><\/pre>\n<p>A\u00f1ada el paquete Couchbase Lite Android en <strong>build.gradle<\/strong>:<\/p>\n<pre><code class=\"language-none\">compile 'com.couchbase.lite:couchbase-lite-android:1.1.0'<\/code><\/pre>\n<p>Crear un <strong>SyncManager.java<\/strong> y a\u00f1adir el c\u00f3digo para iniciar una replicaci\u00f3n pull y push en modo continuo:<\/p>\n<pre><code class=\"language-java\">public class SyncManager {\r\n    private static final String DATABASE_NAME = \"cityexplorer\";\r\n    private static final String SYNC_URL = \"https:\/\/localhost:4984\/db\/\";\r\n    private static final String CITIES_VIEW = \"getCities\";\r\n\r\n    private Context context;\r\n    private Manager manager;\r\n    private Database database;\r\n\r\n    public SyncManager(Context context) {\r\n        this.context = context;\r\n\r\n        openDatabase();\r\n    }\r\n\r\n    private void openDatabase() {\r\n        try {\r\n            manager = new Manager(new AndroidContext(context), Manager.DEFAULT_OPTIONS);\r\n        } catch (IOException e) {\r\n            e.printStackTrace();\r\n        }\r\n\r\n        try {\r\n            database = manager.getDatabase(DATABASE_NAME);\r\n        } catch (CouchbaseLiteException e) {\r\n            e.printStackTrace();\r\n        }\r\n\r\n        startSync();\r\n    }\r\n\r\n    private void startSync() {\r\n        URL url = null;\r\n        try {\r\n            url = new URL(SYNC_URL);\r\n        } catch (MalformedURLException e) {\r\n            e.printStackTrace();\r\n        }\r\n\r\n        Replication push = database.createPushReplication(url);\r\n        push.setContinuous(true);\r\n        push.start();\r\n\r\n        Replication pull = database.createPullReplication(url);\r\n        pull.setContinuous(true);\r\n        pull.start();\r\n    }\r\n\r\n    public Database getDatabase() {\r\n        return database;\r\n    }\r\n\r\n    public void setDatabase(Database database) {\r\n        this.database = database;\r\n    }\r\n}<\/code><\/pre>\n<p>Ejecute la aplicaci\u00f3n y eche un vistazo en LogCat, deber\u00eda ver que la replicaci\u00f3n se ha realizado correctamente. Pero no hay forma de consultar los documentos que se han sincronizado hasta ahora. Para ello, utilizar\u00e1s una Vista Couchbase que indexar\u00e1 los documentos por su <strong>ciudad<\/strong> propiedad.<\/p>\n<p>En <strong>SyncManager.java<\/strong>a\u00f1ade el siguiente m\u00e9todo:<\/p>\n<pre><code class=\"language-java\">private void registerViews() {\r\n    View citiesView = database.getView(CITIES_VIEW);\r\n    citiesView.setMapReduce(new Mapper() {\r\n        @Override\r\n        public void map(Map&lt;String, Object&gt; document, Emitter emitter) {\r\n            if (document.get(\"name\") != null) {\r\n                List<object width=\"300\" height=\"150\"> key = new ArrayList<object>();\r\n                key.add(document.get(\"city\"));\r\n                emitter.emit(key, null);\r\n            }\r\n        }\r\n    }, new Reducer() {\r\n        @Override\r\n        public Object reduce(List<object> keys, List<object> values, boolean rereduce) {\r\n            return new Integer(values.size());\r\n        }\r\n    }, \"7\");\r\n}\r\n\r\nTo query that view, add another method called <strong>consultaCiudades<\/strong> as\u00ed:\r\n<pre>\r\n<code class=\"language-java\">private void queryCities() {\r\n    Query query = database.getView(CITIES_VIEW).createQuery();\r\n    query.setGroupLevel(1);\r\n    try {\r\n        QueryEnumerator enumeration = query.run();\r\n        for (QueryRow row : enumeration) {\r\n            System.out.println(\"Row is \" + row.getValue() + \" and key \" + row.getKey());\r\n        }\r\n    } catch (CouchbaseLiteException e) {\r\n        e.printStackTrace();\r\n    }\r\n}<\/code><\/pre>\n<p>Y llamarlo despu\u00e9s <code>registerViews<\/code> en el <code>openDatabase<\/code> Ejecute la aplicaci\u00f3n y deber\u00eda ver el n\u00famero de plazas de cada ciudad en LogCat:<img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/sync_london_places.png\" \/>Tambi\u00e9n ha configurado la replicaci\u00f3n push, pero a\u00fan no ha persistido ning\u00fan documento localmente. En el <code>onConnected<\/code> m\u00e9todo de <strong>MainActivity.java<\/strong> a\u00f1adir\u00e1 c\u00f3digo para persistir un nuevo documento localmente con un <strong>tipo<\/strong> igual a <strong>perfil<\/strong> y <strong>ciudad<\/strong> con el nombre de la ciudad devuelto por la api de localizaci\u00f3n fusionada.Antes de ejecutar la aplicaci\u00f3n vamos a recapitular los diferentes componentes de esta arquitectura:<img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/app_flow.png\" \/>F\u00edjate en que las flechas est\u00e1n agrupadas por colores:<\/p>\n<ul>\n<li><strong>Naranja<\/strong>: Cuando un usuario abre la aplicaci\u00f3n, el documento de perfil se mantiene localmente y se env\u00eda a Sync Gateway a trav\u00e9s de la replicaci\u00f3n push continua y activa un webhook.<\/li>\n<li><strong>Azul<\/strong>: El App Server gestiona los webhooks e importa las plazas de la ciudad en cuesti\u00f3n a Sync Gateway.<\/li>\n<li><strong>Verde<\/strong>: El usuario correspondiente recibe los documentos seg\u00fan las reglas de acceso definidas en la funci\u00f3n de sincronizaci\u00f3n.<\/li>\n<\/ul>\n<p>En <strong>Verde<\/strong> se producir\u00e1 siempre alg\u00fan tiempo despu\u00e9s de que se abra la aplicaci\u00f3n. Ser\u00eda bueno supervisar la consulta de ciudades en la aplicaci\u00f3n Android para controlar los datos a medida que se extraen de Sync Gateway. Para ello se utilizar\u00e1 un <strong>LiveQuery<\/strong> en lugar de <strong>Consulta<\/strong>. Actualice el <strong>consultaCiudades<\/strong> a lo siguiente:<\/p>\n<pre>\r\n<code class=\"language-java\">private void queryCities() {\r\n    final Query query = database.getView(CITIES_VIEW).createQuery();\r\n    query.setGroupLevel(1);\r\n    LiveQuery liveQuery = query.toLiveQuery();\r\n    liveQuery.addChangeListener(new LiveQuery.ChangeListener() {\r\n        @Override\r\n        public void changed(LiveQuery.ChangeEvent event) {\r\n            try {\r\n                QueryEnumerator enumeration = query.run();\r\n                for (QueryRow row : enumeration) {\r\n                    Log.d(\"CityExplorer\", \"Row is \" + row.getValue() + \" and key \" + row.getKey());\r\n                }\r\n            } catch (CouchbaseLiteException e) {\r\n                e.printStackTrace();\r\n            }\r\n        }\r\n    });\r\n    liveQuery.start();\r\n}<\/code><\/pre>\n<p>Hasta ahora deber\u00eda tener 20 documentos en Sync Gateway y puede comprobarlo en el Admin Dashboard. Reinicie la aplicaci\u00f3n y esto crear\u00e1 el documento de perfil, lo enviar\u00e1 a Sync Gateway para importar 20 lugares alrededor de la ubicaci\u00f3n del usuario. Esto resultar\u00e1 en la adici\u00f3n de 20 nuevos lugares a Sync Gateway:<img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/admin_ui_all_places.png\" \/><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/sync_all_places.png\" \/>Observe que el Sync Gateway tiene ahora 41 documentos (el documento de perfil y 20 lugares m\u00e1s en la ubicaci\u00f3n del dispositivo que ejecuta la aplicaci\u00f3n) y que el LiveQuery de la aplicaci\u00f3n Android devuelve los mismos documentos por ciudad (en este ejemplo 20 en Londres y 20 en Saint-\u00c9tienne-de-Tin\u00e9e).<\/p>\n<h2>Cambio de la funci\u00f3n de sincronizaci\u00f3n<\/h2>\n<p>Hasta ahora ha seguido el tutorial sin crear usuarios. Es decir, todos los dispositivos m\u00f3viles que se conectan a Sync Gateway reciben los mismos documentos. Esto no es manejable a medida que crece el tama\u00f1o de los datos. Adem\u00e1s, si un usuario se encuentra en Saint-\u00c9tienne-de-Tin\u00e9e, no es necesario sincronizar lugares de Londres con su dispositivo. Para a\u00f1adir este filtrado de documentos por dispositivo hay que hacer dos cosas:<\/p>\n<ul>\n<li>Crear usuarios y autenticarse como usuario particular.<\/li>\n<li>Actualice la funci\u00f3n de sincronizaci\u00f3n para que un usuario concreto tenga acceso a los documentos de la ciudad en la que se encuentra.<\/li>\n<\/ul>\n<p>Para crear un usuario se utilizar\u00e1 curl para enviar una petici\u00f3n POST en el puerto admin:<\/p>\n<pre>\r\n<code class=\"language-bash\">$ curl -vX POST :4985\/db\/_user\/ \r\n        -H 'Content-Type: application\/json' \r\n        -d '{\"name\": \"james\", \"password\": \"letmein\"}'<\/code><\/pre>\n<p>En la aplicaci\u00f3n para Android, actualice el <code>startSync<\/code> m\u00e9todo en <strong>SyncManager.java<\/strong> con el autenticador b\u00e1sico pasando las mismas credenciales:<\/p>\n<pre>\r\n<code class=\"language-java\">private void startSync() {\r\n    URL url = null;\r\n    try {\r\n        url = new URL(SYNC_URL);\r\n    } catch (MalformedURLException e) {\r\n        e.printStackTrace();\r\n    }\r\n    Authenticator authenticator = new BasicAuthenticator(\"james\", \"letmein\");\r\n    \r\n    Replication push = database.createPushReplication(url);\r\n    push.setContinuous(true);\r\n    push.setAuthenticator(authenticator);\r\n    push.start();\r\n    \r\n    Replication pull = database.createPullReplication(url);\r\n    pull.setContinuous(true);\r\n    pull.setAuthenticator(authenticator);\r\n    pull.start();\r\n}<\/code><\/pre>\n<p>Navegue hasta el <strong>Sincroniza<\/strong> en el Panel de control del administrador:https:\/\/localhost:4985\/_admin\/db\/db\/syncUpdate la funci\u00f3n de sincronizaci\u00f3n con lo siguiente:<\/p>\n<pre>\r\n<code class=\"language-javascript\">function(doc, oldDoc) {\r\n        if (doc.type == \"profile\") {\r\n          channel(doc.city);\r\n          access(doc._id, doc.city);\r\n        } else if (doc.type == \"city\") {\r\n            channel(doc.city);\r\n        }\r\n      }<\/code><\/pre>\n<p>A continuaci\u00f3n, haga clic en el bot\u00f3n <strong>Modo de vista previa en directo<\/strong> y el banner superior se volver\u00e1 amarillo.<img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/admin_ui_preview_mode.png\" \/>Esto significa que puede probar la Funci\u00f3n de Sincronizaci\u00f3n en documentos aleatorios pero nada se despliega todav\u00eda, esto es s\u00f3lo para probar el resultado. Utilice el bot\u00f3n aleatorio para ver la salida de canal\/acceso dado un documento aleatorio como entrada:<img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/admin_ui_random_doc.png\" \/>Para implementar esta nueva funci\u00f3n de sincronizaci\u00f3n, lo mejor es detener Sync Gateway, actualizar el archivo de configuraci\u00f3n y volver a iniciarlo. Una vez reiniciado Sync Gateway, desinstale la aplicaci\u00f3n del dispositivo y vuelva a ejecutarla. Deber\u00eda observar que se replican los mismos 40 documentos. De hecho, ha actualizado la funci\u00f3n de sincronizaci\u00f3n, pero los documentos que persist\u00edan hasta ahora no han tenido la oportunidad de ejecutarse a trav\u00e9s de la nueva funci\u00f3n de sincronizaci\u00f3n. Para solucionarlo, utilice la funci\u00f3n <strong>resincronizar<\/strong> en la secci\u00f3n siguiente.<\/p>\n<h2>Resincronizar<\/h2>\n<p>Cada vez que modifique la funci\u00f3n de sincronizaci\u00f3n, aseg\u00farese de llamar a la funci\u00f3n <strong>_resync<\/strong> para volver a calcular las reglas de acceso a los canales para todos los documentos existentes en la base de datos:<\/p>\n<pre>\r\n<code class=\"language-none\">$ curl -vX POST https:\/\/localhost:4985\/db\/_resync<\/code><\/pre>\n<p>Borra la aplicaci\u00f3n y rein\u00edciala. Esta vez, s\u00f3lo ver\u00e1 los 20 lugares en LogCat porque el usuario se encuentra en <strong>Saint-\u00c9tienne-de-Tin\u00e9e<\/strong> y ese usuario no tiene acceso al <strong>Londres<\/strong> y, por tanto, no sacar\u00e1 esos documentos.<img decoding=\"async\" src=\"\/wp-content\/original-assets\/2015\/september\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/resync_call.png\" \/><\/p>\n<h2>Conclusi\u00f3n<\/h2>\n<p>En este tutorial, aprendi\u00f3 a utilizar un webhook para importar documentos desde una API de terceros a Sync Gateway mediante un App Server. Tambi\u00e9n utiliz\u00f3 el <strong>resincronizar<\/strong> al cambiar su funci\u00f3n de sincronizaci\u00f3n para actualizar el acceso a los canales.<\/object><\/object><\/object><\/object><\/code><\/p>","protected":false},"excerpt":{"rendered":"<p>With new tools such as Android Public Beta Testing and Testflight for iOS, shipping new updates of a native mobile application more regularly is a growing trend. In addition to changing the business logic and data models more regularly, there [&hellip;]<\/p>","protected":false},"author":51,"featured_media":13873,"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":[9028],"class_list":["post-1971","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 v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Ship an update to your Android app with Couchbase Mobile<\/title>\n<meta name=\"description\" content=\"Change read access in the Sync Function &amp; replicating the changes to an Android app. Check how to ship an update to your Android app with 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\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Couchbase Mobile: Changing read access in the Sync Function and replicating the changes to an Android app\" \/>\n<meta property=\"og:description\" content=\"Change read access in the Sync Function &amp; replicating the changes to an Android app. Check how to ship an update to your Android app with Couchbase Mobile.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-12-16T01:00:01+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-03-04T14:21:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"James Nocentini, Technical Writer, Mobile, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"James Nocentini, Technical Writer, Mobile, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/\"},\"author\":{\"name\":\"James Nocentini, Technical Writer, Mobile, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ec4dfbd349cb4a321fb6a92b71a9a7f6\"},\"headline\":\"Couchbase Mobile: Changing read access in the Sync Function and replicating the changes to an Android app\",\"datePublished\":\"2015-12-16T01:00:01+00:00\",\"dateModified\":\"2019-03-04T14:21:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/\"},\"wordCount\":1923,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Couchbase Mobile\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/\",\"name\":\"Ship an update to your Android app with Couchbase Mobile\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2015-12-16T01:00:01+00:00\",\"dateModified\":\"2019-03-04T14:21:10+00:00\",\"description\":\"Change read access in the Sync Function & replicating the changes to an Android app. Check how to ship an update to your Android app with Couchbase Mobile.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Couchbase Mobile: Changing read access in the Sync Function and replicating the changes to an Android app\"}]},{\"@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\/ec4dfbd349cb4a321fb6a92b71a9a7f6\",\"name\":\"James Nocentini, Technical Writer, Mobile, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/09977bdd14473dc23a125f2f74c3e816\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g\",\"caption\":\"James Nocentini, Technical Writer, Mobile, Couchbase\"},\"description\":\"James Nocentini is the Technical Writer in charge of the documentation for Couchbase Mobile. Previously, he worked as a Developer Advocate and before that as a front-end developer for HouseTrip. He also enjoys writing Android tutorials for raywenderlich.com in his spare time.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/james-nocentini\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Ship an update to your Android app with Couchbase Mobile","description":"Change read access in the Sync Function & replicating the changes to an Android app. Check how to ship an update to your Android app with 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\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/","og_locale":"es_MX","og_type":"article","og_title":"Couchbase Mobile: Changing read access in the Sync Function and replicating the changes to an Android app","og_description":"Change read access in the Sync Function & replicating the changes to an Android app. Check how to ship an update to your Android app with Couchbase Mobile.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/","og_site_name":"The Couchbase Blog","article_published_time":"2015-12-16T01:00:01+00:00","article_modified_time":"2019-03-04T14:21:10+00:00","og_image":[{"width":1800,"height":630,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2022\/11\/couchbase-nosql-dbaas.png","type":"image\/png"}],"author":"James Nocentini, Technical Writer, Mobile, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"James Nocentini, Technical Writer, Mobile, Couchbase","Est. reading time":"14 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/"},"author":{"name":"James Nocentini, Technical Writer, Mobile, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ec4dfbd349cb4a321fb6a92b71a9a7f6"},"headline":"Couchbase Mobile: Changing read access in the Sync Function and replicating the changes to an Android app","datePublished":"2015-12-16T01:00:01+00:00","dateModified":"2019-03-04T14:21:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/"},"wordCount":1923,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","articleSection":["Couchbase Mobile"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/","url":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/","name":"Ship an update to your Android app with Couchbase Mobile","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2015-12-16T01:00:01+00:00","dateModified":"2019-03-04T14:21:10+00:00","description":"Change read access in the Sync Function & replicating the changes to an Android app. Check how to ship an update to your Android app with Couchbase Mobile.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Couchbase Mobile: Changing read access in the Sync Function and replicating the changes to an Android app"}]},{"@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\/ec4dfbd349cb4a321fb6a92b71a9a7f6","name":"James Nocentini, Redactor t\u00e9cnico, M\u00f3vil, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/09977bdd14473dc23a125f2f74c3e816","url":"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g","caption":"James Nocentini, Technical Writer, Mobile, Couchbase"},"description":"James Nocentini es el escritor t\u00e9cnico encargado de la documentaci\u00f3n de Couchbase Mobile. Anteriormente, trabaj\u00f3 como Developer Advocate y antes de eso como desarrollador front-end para HouseTrip. Tambi\u00e9n disfruta escribiendo tutoriales de Android para raywenderlich.com en su tiempo libre.","url":"https:\/\/www.couchbase.com\/blog\/es\/author\/james-nocentini\/"}]}},"authors":[{"term_id":9028,"user_id":51,"is_guest":0,"slug":"james-nocentini","display_name":"James Nocentini, Technical Writer, Mobile, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/0aa80108e5c81e282d705199edae5a25f8ef92abf15cd64f8ff19837abcee09a?s=96&d=mm&r=g","first_name":"James","last_name":"Nocentini","user_url":"","author_category":"","description":"James Nocentini es el escritor t\u00e9cnico encargado de la documentaci\u00f3n de Couchbase Mobile. Anteriormente, trabaj\u00f3 como Developer Advocate y antes de eso como desarrollador front-end para HouseTrip. Tambi\u00e9n disfruta escribiendo tutoriales de Android para raywenderlich.com en su tiempo libre."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/1971","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\/51"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=1971"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/1971\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=1971"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=1971"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=1971"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=1971"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}