{"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\/pt\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/","title":{"rendered":"Couchbase Mobile: Alterando o acesso de leitura na fun\u00e7\u00e3o Sync e replicando as altera\u00e7\u00f5es em um aplicativo Android"},"content":{"rendered":"<p>Com novas ferramentas, como o Android Public Beta Testing e o Testflight para iOS, o envio de novas atualiza\u00e7\u00f5es de um aplicativo m\u00f3vel nativo com mais regularidade \u00e9 uma tend\u00eancia crescente.<\/p>\n<p>Al\u00e9m de alterar a l\u00f3gica comercial e os modelos de dados com mais regularidade, tamb\u00e9m \u00e9 necess\u00e1rio oferecer suporte a vers\u00f5es anteriores. Ao contr\u00e1rio de um site em que o usu\u00e1rio sempre acessa a vers\u00e3o mais recente no navegador, os aplicativos m\u00f3veis podem permanecer no dispositivo do usu\u00e1rio por um longo per\u00edodo de tempo sem serem atualizados.<\/p>\n<p>Neste tutorial, voc\u00ea aprender\u00e1 a enviar uma atualiza\u00e7\u00e3o para seu aplicativo Android com o Couchbase Mobile. Voc\u00ea usar\u00e1 um webhook do Sync Gateway para importar dados de uma API de terceiros sob demanda (neste caso, a API do Google Places) com o Node.js. Na primeira inst\u00e2ncia, o aplicativo Android sincronizar\u00e1 todos os dados e, em uma vers\u00e3o subsequente do aplicativo, extrair\u00e1 apenas um subconjunto deles. Ao alterar as regras de acesso na fun\u00e7\u00e3o Sync, voc\u00ea usar\u00e1 o Sync Gateway <strong>ressincroniza\u00e7\u00e3o<\/strong> para reconstruir as regras de acesso de acordo com a Sync Function atualizada.<\/p>\n<p>Vamos come\u00e7ar!<\/p>\n<p>A ordem em que voc\u00ea montar\u00e1 os diferentes componentes \u00e9 a seguinte:<\/p>\n<ol>\n<li>Instala\u00e7\u00e3o do Sync Gateway<\/li>\n<li>Configura\u00e7\u00e3o do webhook<\/li>\n<li>Cria\u00e7\u00e3o do servidor de aplicativos<\/li>\n<li>Cria\u00e7\u00e3o do aplicativo Android<\/li>\n<\/ol>\n<h2>Primeiros passos<\/h2>\n<p>Fa\u00e7a o download do Sync Gateway e descompacte o arquivo:<\/p>\n<p>https:\/\/www.couchbase.com\/nosql-databases\/downloads#Couchbase_Mobile<\/p>\n<p>Voc\u00ea pode encontrar o bin\u00e1rio do Sync Gateway no diret\u00f3rio <strong>caixa<\/strong> e exemplos de arquivos de configura\u00e7\u00e3o na pasta <strong>exemplos<\/strong> pasta. Copie o <strong>basic-walrus-bucket.json<\/strong> na raiz do seu projeto:<\/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 o Sync Gateway:<\/p>\n<pre><code class=\"language-none\">$ ~\/Downloads\/couchbase-sync-gateway\/bin\/sync_gateway<\/code><\/pre>\n<h2>Webhook do gateway de sincroniza\u00e7\u00e3o<\/h2>\n<p>O webhook \u00e9 definido no arquivo de configura\u00e7\u00e3o que voc\u00ea criou acima e recebe um <strong>url<\/strong> para o POST e um <strong>fun\u00e7\u00e3o de filtro<\/strong> (opcional). Adicione o <strong>manipuladores de eventos<\/strong> campo em <strong>sync-gateway-config.json<\/strong> com as seguintes propriedades:<\/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>Veja a seguir o que cada novo campo est\u00e1 fazendo:<\/p>\n<ul>\n<li><strong>manipulador<\/strong>: Voc\u00ea est\u00e1 especificando o tipo de evento a ser <strong>webhook<\/strong><\/li>\n<li><strong>url<\/strong>: O URL para o qual enviar a solicita\u00e7\u00e3o POST com o documento no corpo da mensagem<\/li>\n<li><strong>filtro<\/strong>: Uma fun\u00e7\u00e3o escrita em JavaScript para acionar o webhook somente se ele retornar <strong>verdadeiro<\/strong>. Observe aqui que o webhook ser\u00e1 executado somente se o documento tiver um <strong>tipo<\/strong> propriedade igual a <strong>perfil<\/strong><\/li>\n<\/ul>\n<p>Salve as altera\u00e7\u00f5es e reinicie o 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 aplicativos<\/h2>\n<p>Nesta se\u00e7\u00e3o, voc\u00ea usar\u00e1 o Node.js e a estrutura Express para configurar um App Server para lidar com o webhook. No mesmo diret\u00f3rio, instale os m\u00f3dulos Node.js necess\u00e1rios:<\/p>\n<pre><code class=\"language-bash\">npm install express body-parser --save<\/code><\/pre>\n<p>Em um novo arquivo chamado <strong>servidor.js<\/strong> adicione o seguinte 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 o servidor de aplicativos Node.js executando <strong>servidor de n\u00f3.js<\/strong> e salve um documento no Sync Gateway usando a API REST para garantir que o webhook esteja funcionando:<\/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>Voc\u00ea dever\u00e1 ver a seguinte sa\u00edda nos logs do 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>Excelente! O webhook est\u00e1 funcionando. Em seguida, voc\u00ea adicionar\u00e1 algum c\u00f3digo para importar os dados JSON da API Places para o Sync Gateway. Para isso, voc\u00ea usar\u00e1 o RxJS e o Request. O c\u00f3digo que lida com mais de um evento ou computa\u00e7\u00e3o ass\u00edncrona se complica rapidamente. O RxJS faz esses c\u00e1lculos <em>cidad\u00e3os de primeira classe<\/em> e fornece um modelo que permite APIs leg\u00edveis e compostas. E o m\u00f3dulo Request \u00e9 a biblioteca de fato para tornar as solicita\u00e7\u00f5es http no NodeJS mais simples do que nunca. No mesmo diret\u00f3rio, v\u00e1 em frente e instale as depend\u00eancias:<\/p>\n<pre><code class=\"language-bash\">$ npm install request rx --save<\/code><\/pre>\n<p>C\u00f3pia <strong>requestRx.js<\/strong> a partir deste <a href=\"https:\/\/github.com\/couchbaselabs\/mini-hacks\/tree\/master\/sync-gateway-resync-android\">Reposit\u00f3rio do GitHub<\/a> na pasta do seu projeto. Estamos simplesmente envolvendo a API de solicita\u00e7\u00e3o em constru\u00e7\u00f5es RxJS (flatMap, filter, subscribe...). Por exemplo, em vez de usar <code>request.get<\/code>voc\u00ea usar\u00e1 <code>requestRx.get<\/code>.<\/p>\n<p>Abra um novo arquivo chamado <strong>sync.js<\/strong>, exigem que o <strong>requestRx<\/strong> e <strong>Rx<\/strong> e adicione o seguinte 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>Veja a seguir o que est\u00e1 acontecendo passo a passo:<\/p>\n<ol>\n<li>Obter os Locais que correspondem \u00e0 consulta <strong>restaurantes em Londres<\/strong>. Use o recurso de interpola\u00e7\u00e3o de strings do ES 6 na url.<\/li>\n<li>O <strong><em>volume<\/em>documentos<\/strong> \u00e9 muito conveniente para a importa\u00e7\u00e3o de grandes conjuntos de dados para uma inst\u00e2ncia do Sync Gateway. Leia mais sobre ele na se\u00e7\u00e3o <a href=\"https:\/\/developer.couchbase.com\/mobile\/develop\/references\/sync-gateway\/rest-api\/database\/post-bulk-docs\/index.html\">documentos<\/a>.<\/li>\n<li>Depois de salvar o documento e salvar a foto como anexo, voc\u00ea deve primeiro obter a imagem da API do Places. Observe a <strong>codifica\u00e7\u00e3o<\/strong> \u00e9 definida como <strong>nulo<\/strong>. Isso \u00e9 exigido pelo m\u00f3dulo Request para qualquer corpo de resposta que n\u00e3o seja uma string. Leia mais sobre isso na se\u00e7\u00e3o <a href=\"https:\/\/github.com\/request\/request#user-content-requestoptions-callback\">Solicitar documentos<\/a>.<\/li>\n<li>Voc\u00ea deve informar ao Sync Gateway em qual documento (especificando o ID do documento) e a revis\u00e3o desse documento (especificando o n\u00famero da revis\u00e3o) salvar esse anexo.<\/li>\n<\/ol>\n<p>Observe que na \u00faltima linha voc\u00ea est\u00e1 exportando o <strong>SyncRequest<\/strong> objeto. Em <strong>servidor.js<\/strong>, exigem que o <strong>sync.js<\/strong> e chamar o arquivo <strong>syncRequest<\/strong> passando o m\u00e9todo <strong>cidade<\/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>Voc\u00ea deve ter notado que <strong>sync.js<\/strong> \u00e9 escrito com a sintaxe ES6. Em execu\u00e7\u00e3o <strong>servidor de n\u00f3.js<\/strong> n\u00e3o funcionar\u00e1 e voc\u00ea deve primeiro instalar o <a href=\"https:\/\/babeljs.io\/\">Babel<\/a> m\u00f3dulo globalmente:<\/p>\n<pre><code class=\"language-bash\">npm install babel-node -g<\/code><\/pre>\n<p>Agora voc\u00ea pode executar o <strong>sync.js<\/strong> de forma independente com o seguinte comando:<\/p>\n<pre><code class=\"language-bash\">babel-node -e \"require('.\/sync.js').syncRequest('London')\"<\/code><\/pre>\n<p>Abra o Admin Dashboard para monitorar os documentos que foram salvos no Sync Gateway.<\/p>\n<p>https:\/\/localhost:4985\/_admin\/<\/p>\n<p>Agora voc\u00ea deve ver 20 documentos, sendo que cada um deles \u00e9 um local em 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>Cria\u00e7\u00e3o do aplicativo Android<\/h2>\n<p>Nesta se\u00e7\u00e3o, voc\u00ea aprender\u00e1 a usar o SDK do Google Maps no Android para obter a cidade em que o usu\u00e1rio est\u00e1 localizado no momento. Com essas informa\u00e7\u00f5es, voc\u00ea criar\u00e1 um documento do tipo <strong>perfil<\/strong> para armazenar a cidade atual.<\/p>\n<p>Abra o Android Studio e selecione <strong>Iniciar um novo projeto do Android Studio<\/strong> do <strong>In\u00edcio r\u00e1pido<\/strong> menu.<\/p>\n<p>Nomear o aplicativo <strong>CityExplorer<\/strong>defina um dom\u00ednio da empresa e um local do projeto adequados e clique em <strong>Pr\u00f3ximo<\/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>Na caixa de di\u00e1logo Target Android Devices (Dispositivos Android de destino), certifique-se de marcar <strong>Telefone e tablet<\/strong>defina o SDK m\u00ednimo como <strong>API 22: Android 5.1 (Lollipop)<\/strong> para ambos, e clique em <strong>Pr\u00f3ximo<\/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>No dia seguinte <strong>Adicionar uma atividade ao Mobile<\/strong> selecione Add <strong>Atividade em branco<\/strong> e nomeie a atividade <strong>Atividade 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>Voc\u00ea usar\u00e1 o <strong>provedor de localiza\u00e7\u00e3o fundido<\/strong> para recuperar a \u00faltima localiza\u00e7\u00e3o conhecida do dispositivo. Em <strong>build.gradle<\/strong>adicione a seguinte depend\u00eancia:<\/p>\n<pre><code class=\"language-groovy\">compile 'com.google.android.gms:play-services:7.5.0'<\/code><\/pre>\n<p>Adicionar uma permiss\u00e3o de solicita\u00e7\u00e3o de localiza\u00e7\u00e3o em <strong>AndroidManifest.xml<\/strong> no <strong>manifesto<\/strong> Etiqueta XML:<\/p>\n<pre><code class=\"language-xml\"><\/code><\/pre>\n<p>Em <strong>MainActivity.java<\/strong>adicione um novo m\u00e9todo chamado <strong>criar cliente GoogleApi<\/strong> para inicializar o SDK da API do Google e chamar o m\u00e9todo em <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>Em seguida, voc\u00ea far\u00e1 <strong>Atividade principal<\/strong> implementar o <strong>GoogleApiClient.ConnectionCallbacks<\/strong> e <strong>GoogleApiClient.OnConnectionFailedListener<\/strong> e recuperar o local em <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>Execute o aplicativo e voc\u00ea ver\u00e1 a cidade atual exibida no meio da tela:<\/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>Em seguida, voc\u00ea adicionar\u00e1 o Couchbase Lite ao seu projeto. Em <strong>build.gradle<\/strong> adicione o seguinte:<\/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>Adicione o pacote do Couchbase Lite para Android em <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>Criar um <strong>SyncManager.java<\/strong> e adicione o c\u00f3digo para iniciar uma replica\u00e7\u00e3o pull e push no modo cont\u00ednuo:<\/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>Execute o aplicativo e d\u00ea uma olhada no LogCat, e voc\u00ea ver\u00e1 que a replica\u00e7\u00e3o foi bem-sucedida. Mas n\u00e3o h\u00e1 como consultar os documentos que foram sincronizados at\u00e9 o momento. Para fazer isso, voc\u00ea usar\u00e1 um Couchbase View que indexar\u00e1 os documentos por seus <strong>cidade<\/strong> propriedade.<\/p>\n<p>Em <strong>SyncManager.java<\/strong>adicione o seguinte 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>consultarCidades<\/strong> assim:\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>E o chamem depois <code>registrar visualiza\u00e7\u00f5es<\/code> no <code>openDatabase<\/code> Execute o aplicativo e voc\u00ea ver\u00e1 o n\u00famero de locais em cada cidade no 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\" \/>Voc\u00ea tamb\u00e9m configurou a replica\u00e7\u00e3o por push, mas ainda n\u00e3o persistiu nenhum documento localmente. Na se\u00e7\u00e3o <code>onConnected<\/code> m\u00e9todo de <strong>MainActivity.java<\/strong> voc\u00ea adicionar\u00e1 c\u00f3digo para manter um novo documento localmente com um <strong>tipo<\/strong> propriedade igual a <strong>perfil<\/strong> e <strong>cidade<\/strong> Antes de executar o aplicativo, vamos recapitular os diferentes componentes dessa arquitetura:<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\" \/>Observe que as setas est\u00e3o agrupadas por cor:<\/p>\n<ul>\n<li><strong>Laranja<\/strong>: Quando um usu\u00e1rio abre o aplicativo, o documento de perfil \u00e9 mantido localmente e enviado ao Sync Gateway por meio da replica\u00e7\u00e3o cont\u00ednua por push e aciona um webhook.<\/li>\n<li><strong>Azul<\/strong>: O App Server lida com os webhooks e importa os locais de uma determinada cidade para o Sync Gateway.<\/li>\n<li><strong>Verde<\/strong>: O usu\u00e1rio apropriado recebe os documentos de acordo com as regras de acesso definidas na Fun\u00e7\u00e3o de sincroniza\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>O <strong>Verde<\/strong> sempre ocorrer\u00e1 algum tempo depois que o aplicativo for aberto. Seria bom monitorar a consulta de cidades no aplicativo Android para monitorar os dados \u00e0 medida que eles s\u00e3o extra\u00eddos do Sync Gateway. Voc\u00ea far\u00e1 isso usando um <strong>LiveQuery<\/strong> no lugar de um <strong>Consulta<\/strong>. Atualizar o <strong>consultarCidades<\/strong> para o seguinte:<\/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>At\u00e9 o momento, voc\u00ea deve ter 20 documentos no Sync Gateway e pode verificar isso no painel do administrador. Reinicie o aplicativo e isso criar\u00e1 o documento de perfil e o enviar\u00e1 ao Sync Gateway para importar 20 locais em torno da localiza\u00e7\u00e3o do usu\u00e1rio. Isso resultar\u00e1 na adi\u00e7\u00e3o de 20 novos locais ao 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 o Sync Gateway agora tem 41 documentos (o documento de perfil e mais 20 locais na localiza\u00e7\u00e3o do dispositivo que est\u00e1 executando o aplicativo) e o LiveQuery no aplicativo Android retorna os mesmos documentos por cidade (neste exemplo, 20 em Londres e 20 em Saint-\u00c9tienne-de-Tin\u00e9e).<\/p>\n<h2>Altera\u00e7\u00e3o da fun\u00e7\u00e3o de sincroniza\u00e7\u00e3o<\/h2>\n<p>At\u00e9 agora, voc\u00ea tem seguido o tutorial sem criar usu\u00e1rios. Ou seja, todos os dispositivos m\u00f3veis que se conectam ao Sync Gateway recebem os mesmos documentos. Isso n\u00e3o \u00e9 gerenci\u00e1vel \u00e0 medida que o tamanho dos dados aumenta. Al\u00e9m disso, se um usu\u00e1rio estiver localizado em Saint-\u00c9tienne-de-Tin\u00e9e, n\u00e3o h\u00e1 necessidade de sincronizar lugares em Londres com o dispositivo dele. Para adicionar essa filtragem de documentos por dispositivo, voc\u00ea far\u00e1 duas coisas:<\/p>\n<ul>\n<li>Crie usu\u00e1rios e autentique-se como um usu\u00e1rio espec\u00edfico.<\/li>\n<li>Atualize a fun\u00e7\u00e3o de sincroniza\u00e7\u00e3o para dar a um determinado usu\u00e1rio acesso aos documentos na cidade em que ele est\u00e1 localizado.<\/li>\n<\/ul>\n<p>Para criar um usu\u00e1rio, voc\u00ea usar\u00e1 o curl para enviar uma solicita\u00e7\u00e3o POST na porta de administra\u00e7\u00e3o:<\/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>No aplicativo Android, atualize o <code>startSync<\/code> m\u00e9todo em <strong>SyncManager.java<\/strong> com o autenticador b\u00e1sico passando as mesmas credenciais:<\/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 at\u00e9 a se\u00e7\u00e3o <strong>Sincroniza\u00e7\u00e3o<\/strong> no painel de controle do administrador: https:\/\/localhost:4985\/_admin\/db\/db\/syncUpdate a fun\u00e7\u00e3o Sync com o seguinte:<\/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>Em seguida, clique no \u00edcone <strong>Modo de visualiza\u00e7\u00e3o ao vivo<\/strong> e o banner superior dever\u00e1 ficar amarelo.<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\" \/>Isso significa que voc\u00ea pode testar a fun\u00e7\u00e3o de sincroniza\u00e7\u00e3o em documentos aleat\u00f3rios, mas nada foi implantado ainda; isso serve apenas para testar o resultado. Use o bot\u00e3o aleat\u00f3rio para ver a sa\u00edda do canal\/acesso com um documento aleat\u00f3rio 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 de fato essa nova fun\u00e7\u00e3o de sincroniza\u00e7\u00e3o, \u00e9 recomend\u00e1vel interromper o Sync Gateway, atualizar o arquivo de configura\u00e7\u00e3o e inici\u00e1-lo novamente. Depois de reiniciar o Sync Gateway, desinstale o aplicativo do dispositivo e execute-o novamente. Voc\u00ea dever\u00e1 notar que os mesmos 40 documentos est\u00e3o sendo replicados. Na verdade, voc\u00ea atualizou a Sync Function, mas os documentos que foram mantidos at\u00e9 agora n\u00e3o tiveram a chance de passar pela nova Sync Function. Para corrigir isso, voc\u00ea usar\u00e1 a fun\u00e7\u00e3o <strong>ressincroniza\u00e7\u00e3o<\/strong> na se\u00e7\u00e3o a seguir.<\/p>\n<h2>Ressincroniza\u00e7\u00e3o<\/h2>\n<p>Sempre que voc\u00ea modificar a fun\u00e7\u00e3o Sync, certifique-se de chamar a fun\u00e7\u00e3o <strong>_resync<\/strong> para recalcular as regras de acesso ao canal para todos os documentos existentes no banco de dados:<\/p>\n<pre>\r\n<code class=\"language-none\">$ curl -vX POST https:\/\/localhost:4985\/db\/_resync<\/code><\/pre>\n<p>Exclua o aplicativo e reinicie-o. Dessa vez, voc\u00ea ver\u00e1 apenas os 20 locais no LogCat porque o usu\u00e1rio est\u00e1 localizado em <strong>Saint-\u00c9tienne-de-Tin\u00e9e<\/strong> e esse usu\u00e1rio n\u00e3o tem acesso ao <strong>Londres<\/strong> e, portanto, n\u00e3o obter\u00e1 esses 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>Conclus\u00e3o<\/h2>\n<p>Neste tutorial, voc\u00ea aprendeu a usar um webhook para importar documentos de uma API de terceiros para o Sync Gateway usando um App Server. Voc\u00ea tamb\u00e9m usou o <strong>ressincroniza\u00e7\u00e3o<\/strong> ao alterar sua Sync Function para atualizar o acesso aos canais.<\/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 v26.0 (Yoast SEO v26.0) - 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\/pt\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\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\/pt\/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\":\"pt-BR\",\"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\":\"pt-BR\",\"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\":\"pt-BR\",\"@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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\":\"pt-BR\",\"@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\/pt\/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\/pt\/couchbase-mobile-changing-read-access-in-the-sync-function-and-replicating-the-changes-to-an-android-app\/","og_locale":"pt_BR","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\/pt\/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":"pt-BR","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":"pt-BR","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":"pt-BR","@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":"Blog do Couchbase","description":"Couchbase, o banco de dados 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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@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, redator t\u00e9cnico, celular, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@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 \u00e9 o redator t\u00e9cnico respons\u00e1vel pela documenta\u00e7\u00e3o do Couchbase Mobile. Anteriormente, ele trabalhou como Developer Advocate e, antes disso, como desenvolvedor front-end da HouseTrip. Ele tamb\u00e9m gosta de escrever tutoriais sobre Android para raywenderlich.com em seu tempo livre.","url":"https:\/\/www.couchbase.com\/blog\/pt\/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","author_category":"","last_name":"Nocentini","first_name":"James","job_title":"","user_url":"","description":"James Nocentini \u00e9 o redator t\u00e9cnico respons\u00e1vel pela documenta\u00e7\u00e3o do Couchbase Mobile. Anteriormente, ele trabalhou como Developer Advocate e, antes disso, como desenvolvedor front-end da HouseTrip. Ele tamb\u00e9m gosta de escrever tutoriais sobre Android para raywenderlich.com em seu tempo livre."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/1971","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/51"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=1971"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/1971\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=1971"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=1971"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=1971"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=1971"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}