{"id":2456,"date":"2016-12-15T15:00:00","date_gmt":"2016-12-15T15:00:00","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2456"},"modified":"2025-06-13T20:15:37","modified_gmt":"2025-06-14T03:15:37","slug":"data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/","title":{"rendered":"Sincroniza\u00e7\u00e3o de dados com o Couchbase em aplicativos m\u00f3veis h\u00edbridos do Ionic 2"},"content":{"rendered":"<p>No ano passado, escrevi sobre o uso de <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/using-couchbase-in-your-ionic-framework-application-part-1\/\">Couchbase Mobile em um aplicativo m\u00f3vel do Ionic Framework<\/a>. Naquela \u00e9poca, us\u00e1vamos o Ionic Framework 1.0 e o AngularJS 1.0. A tecnologia mudou ao longo dos meses e passamos do que pareciam ser estruturas antigas para itera\u00e7\u00f5es muito mais modernas.<\/p>\n<p>Com o lan\u00e7amento do Angular 2 e o Ionic 2 se aproximando da vers\u00e3o est\u00e1vel, achei que seria uma \u00f3tima ideia revisitar o que fiz anteriormente e explorar o Couchbase Mobile em um aplicativo Ionic 2 para Android e iOS.<\/p>\n<h2 id=\"the-requirements\">Os requisitos<\/h2>\n<p>Para tornar esse projeto poss\u00edvel, precisaremos de alguns itens instalados e dispon\u00edveis. Eles s\u00e3o os seguintes:<\/p>\n<ul>\n<li>Node.js 4.0+<\/li>\n<li>Estrutura Ionic 2.0<\/li>\n<li>O Android SDK ou o Xcode<\/li>\n<li>Gateway de sincroniza\u00e7\u00e3o do Couchbase<\/li>\n<\/ul>\n<p>O Ionic Framework usa o Node Package Manager (NPM) que vem com o Node.js para lidar com todas as depend\u00eancias do projeto. Para criar aplicativos Android, precisaremos do Android SDK instalado e, para criar aplicativos iOS, precisaremos de um Mac com o Xcode instalado. Por fim, se quisermos demonstrar a sincroniza\u00e7\u00e3o, precisaremos do Couchbase Sync Gateway instalado e dispon\u00edvel.<\/p>\n<h2 id=\"creating-a-new-ionic-2-project\">Cria\u00e7\u00e3o de um novo projeto Ionic 2<\/h2>\n<p>Vamos criar um aplicativo de lista de tarefas muito simples com o Ionic 2, o Angular 2 e o TypeScript. Essa lista de tarefas ser\u00e1 sincronizada entre dispositivos e plataformas, conforme demonstrado na imagem animada abaixo.<\/p>\n<div class=\"figure\"><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2016\/december\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/ionic-2-couchbase.gif\" alt=\"Ionic 2 with Couchbase\" \/><\/div>\n<p>Esse \u00e9 o mesmo aplicativo que vimos no tutorial do Ionic Framework 1.0, bem como em muitos outros <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/mobile-tutorials\/\">tutoriais para celular<\/a>. \u00c9 o mesmo aplicativo porque serve como um exemplo muito \u00fatil.<\/p>\n<p>Para simplificar, come\u00e7aremos com um projeto novo. No prompt de comando (Windows) ou no Terminal (Linux e Mac), execute o seguinte:<\/p>\n<pre><code>ionic start CouchbaseProject blank --v2\r\ncd CouchbaseProject\r\nionic platform add ios\r\nionic platform add android<\/code><\/pre>\n<p>Os comandos acima criar\u00e3o um projeto do Ionic Framework 2.0 que usa Angular 2 e TypeScript. Embora eu tenha optado por adicionar as plataformas de compila\u00e7\u00e3o iOS e Android, n\u00e3o poderemos compilar para iOS a menos que estejamos usando um Mac com o Xcode instalado.<\/p>\n<p>Esse projeto depende do <a href=\"https:\/\/github.com\/couchbaselabs\/Couchbase-Lite-PhoneGap-Plugin\">Plug-in do Couchbase para PhoneGap<\/a> para funcionar. N\u00e3o se assuste. Embora o nome diga PhoneGap, ele \u00e9, na verdade, apenas um plug-in do Apache Cordova, algo que \u00e9 muito compat\u00edvel com o Ionic 2. Para instalar esse plug-in no projeto, execute o seguinte:<\/p>\n<pre><code>ionic plugin add https:\/\/github.com\/couchbaselabs\/Couchbase-Lite-PhoneGap-Plugin.git<\/code><\/pre>\n<p>O plug-in Couchbase Lite para o Apache Cordova funciona inteiramente com base nas APIs RESTful dispon\u00edveis. Pessoalmente, prefiro n\u00e3o trabalhar com APIs em meu aplicativo, por isso criei um bom wrapper JavaScript para transformar as APIs em uma classe agrad\u00e1vel. O wrapper,<a href=\"https:\/\/github.com\/couchbaselabs\/cordova-couchbase\">cordova-couchbase<\/a>permitir\u00e1 que voc\u00ea use m\u00e9todos em vez de se preocupar com solicita\u00e7\u00f5es HTTP para pontos de extremidade.<\/p>\n<p>Para instalar o cordova-couchbase em seu projeto, execute o seguinte:<\/p>\n<pre><code>npm install cordova-couchbase --save<\/code><\/pre>\n<p>Neste ponto, estamos prontos para come\u00e7ar a desenvolver o aplicativo Ionic 2.<\/p>\n<h2 id=\"managing-couchbase-via-an-angular-2-provider\">Gerenciando o Couchbase por meio de um provedor Angular 2<\/h2>\n<p>Ao trabalhar com bancos de dados em um aplicativo Angular 2, \u00e9 uma boa ideia mant\u00ea-los em um servi\u00e7o, tamb\u00e9m conhecido como provedor. Isso nos permite n\u00e3o apenas inicializar grande parte da l\u00f3gica do banco de dados em um \u00fanico arquivo, mas tamb\u00e9m manter nossa camada de banco de dados separada do restante do nosso c\u00f3digo.<\/p>\n<p>Usando a CLI do Ionic, execute o seguinte para gerar uma classe de provedor:<\/p>\n<pre><code>ionic g provider CouchbaseProvider<\/code><\/pre>\n<p>Essencialmente, o comando apenas cria um diret\u00f3rio e um arquivo em <strong>src\/providers\/couchbase-provider.ts<\/strong> dentro do projeto. Esse provedor deve se parecer com o seguinte:<\/p>\n<pre class=\"whitespace-after:1 lang:default decode:true\"><code>import { Injectable } from '@angular\/core';\r\nimport { Http } from '@angular\/http';\r\nimport { Platform } from 'ionic-angular';\r\nimport { Couchbase, Database } from 'cordova-couchbase\/core';\r\nimport 'rxjs\/add\/operator\/map'; \r\n\r\n@Injectable()\r\nexport class CouchbaseProvider {\r\n    public constructor(public http:Http) { }\r\n}<\/code><\/pre>\n<p>Vamos come\u00e7ar a pensar em como nosso servi\u00e7o do Couchbase funcionar\u00e1 e nas partes do c\u00f3digo que ser\u00e3o incorporadas a ele para que seja um sucesso.<\/p>\n<p>Queremos que o nosso servi\u00e7o de banco de dados funcione como um singleton, ou seja, queremos que uma \u00fanica classe de banco de dados seja instanciada para todo o aplicativo. Como se fosse um servi\u00e7o compartilhado. Podemos configurar isso por meio da fun\u00e7\u00e3o <code>construtor<\/code> do nosso provedor:<\/p>\n<pre class=\"whitespace-after:1 lang:js decode:true\">private isInstantiated:boolean;\r\nprivate database:Database;\r\npublic constructor(public http:Http, platform:Platform) {\r\n    if(!this.isInstantiated) {\r\n        platform.ready().then(() =&gt; {\r\n            (new Couchbase()).openDatabase(\"nraboy\").then(database =&gt; {\r\n                this.database = database; \r\n                this.isInstantiated = true;\r\n            }, error =&gt; {\r\n                console.error(error);\r\n            });\r\n        });\r\n    }\r\n}<\/pre>\n<p>Ent\u00e3o, o que est\u00e1 acontecendo no c\u00f3digo acima at\u00e9 agora? Primeiro, criamos duas vari\u00e1veis privadas. O booleano nos informar\u00e1 se o banco de dados j\u00e1 foi instanciado. A vari\u00e1vel <code>Banco de dados<\/code> manter\u00e1 o banco de dados aberto no momento.<\/p>\n<p>Dentro do <code>construtor<\/code> estamos fazendo a verifica\u00e7\u00e3o da l\u00f3gica condicional. Como o plug-in do Apache Cordova usa c\u00f3digo nativo, precisamos ter certeza de que o dispositivo est\u00e1 pronto. Isso \u00e9 demonstrado por meio do uso do m\u00e9todo <code>plataforma.ready<\/code> m\u00e9todo. Quando o dispositivo estiver pronto, poderemos abrir um banco de dados, mesmo que ele n\u00e3o exista, e defini-lo em nossa vari\u00e1vel privada.<\/p>\n<pre><code>public getDatabase() {\r\n    return this.database;\r\n}<\/code><\/pre>\n<p>O banco de dados aberto pode ser recuperado de nosso provedor usando o <code>getDatabase<\/code> m\u00e9todo.<\/p>\n<p>Ainda n\u00e3o terminamos com o <code>Provedor do Couchbase<\/code> ainda. Provavelmente, devemos pensar em criar nossas exibi\u00e7\u00f5es de MapReduce para consultas futuras e configurar nosso ouvinte de altera\u00e7\u00f5es. Tudo isso ocorrer\u00e1 na classe <code>construtor<\/code> depois de definir o banco de dados aberto.<\/p>\n<p>Por exemplo, agora vamos considerar o seguinte:<\/p>\n<pre class=\"whitespace-after:1 lang:default decode:true\">private isInstantiated:boolean;\r\nprivate database:Database;\r\nprivate listener:EventEmitter = new EventEmitter();\r\n \r\npublic constructor(public http:Http, platform:Platform) {\r\n    if(!this.isInstantiated) {\r\n        platform.ready().then(() =&gt; {\r\n            (new Couchbase()).openDatabase(\"nraboy\").then(database =&gt; {\r\n                this.database = database;\r\n                let views = {\r\n                    items: {\r\n                        map:function(doc) {\r\n                            if (doc.type == \"list\" &amp;&amp; doc.title) {\r\n                                emit(doc._id,{ title: doc.title, rev: doc._rev })\r\n                            }\r\n                        }.toString()\r\n                    }\r\n                };\r\n                this.database.createDesignDocument(\"_design\/todo\", views);\r\n                this.database.listen(change =&gt; {\r\n                    this.listener.emit(change.detail);\r\n                });\r\n                this.isInstantiated = true;\r\n            },error =&gt; {\r\n                console.error(error);\r\n            });\r\n        });\r\n    }\r\n}<\/pre>\n<p>No c\u00f3digo acima, adicionamos um <code>ouvinte<\/code> que emitir\u00e1 altera\u00e7\u00f5es que podem ser assinadas em nosso c\u00f3digo do Angular 2. Dentro da vari\u00e1vel <code>construtor<\/code> criamos uma visualiza\u00e7\u00e3o MapReduce chamada <code>itens<\/code> com l\u00f3gica que emitir\u00e1 pares de valores-chave somente se o documento contiver uma propriedade chamada <code>tipo<\/code> que \u00e9 igual a \"list\" e uma propriedade chamada <code>t\u00edtulo<\/code> que pode ser igual a qualquer coisa.<\/p>\n<p>A visualiza\u00e7\u00e3o \u00e9 ent\u00e3o adicionada a um documento de design de nossa escolha e o ouvinte \u00e9 ativado. Com o ouvinte ativado, qualquer altera\u00e7\u00e3o no banco de dados o acionar\u00e1. Isso significa que se adicionarmos um documento, alterarmos um documento ou excluirmos um documento, o ouvinte emitir\u00e1 a altera\u00e7\u00e3o.<\/p>\n<pre><code>public getChangeListener(): EventEmitter {\r\n    return this.listener;\r\n}<\/code><\/pre>\n<p>O ouvinte pode ser acessado de v\u00e1rias p\u00e1ginas do aplicativo chamando a fun\u00e7\u00e3o <code>getChangeListener<\/code> fun\u00e7\u00e3o.<\/p>\n<p>O provedor foi criado, mas n\u00e3o est\u00e1 sendo compartilhado no aplicativo no momento. Para fazer isso, precisamos import\u00e1-lo para o Angular 2 <code>@NgModule<\/code> encontrado no bloco <strong>src\/app\/app.module.ts<\/strong> arquivo. Quando conclu\u00eddo, esse arquivo ter\u00e1 a apar\u00eancia a seguir:<\/p>\n<pre><code>import { NgModule, ErrorHandler } from '@angular\/core';\r\nimport { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';\r\nimport { MyApp } from '.\/app.component';\r\nimport { HomePage } from '..\/pages\/home\/home';\r\n\r\nimport { CouchbaseProvider } from \"..\/providers\/couchbase-provider\";\r\n\r\n@NgModule({\r\n    declarations: [\r\n        MyApp,\r\n        HomePage\r\n    ],\r\n    imports: [\r\n        IonicModule.forRoot(MyApp)\r\n    ],\r\n    bootstrap: [IonicApp],\r\n    entryComponents: [\r\n        MyApp,\r\n        HomePage\r\n    ],\r\n    providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}, CouchbaseProvider]\r\n})\r\nexport class AppModule {}<\/code><\/pre>\n<p>Observe que o provedor foi importado e adicionado ao <code>provedores<\/code> array? Agora podemos nos concentrar em adicionar a l\u00f3gica do aplicativo.<\/p>\n<h2 id=\"using-couchbase-within-the-ionic-2-application\">Uso do Couchbase no aplicativo Ionic 2<\/h2>\n<p>Provavelmente, \u00e9 uma boa ideia abrir nosso banco de dados quando o aplicativo for iniciado. Embora possamos fazer isso quando a primeira p\u00e1gina for carregada, n\u00e3o \u00e9 necess\u00e1rio.<\/p>\n<p>Abra o arquivo <strong>src\/app\/app.component.ts<\/strong> e inclua o seguinte c\u00f3digo TypeScript:<\/p>\n<pre class=\"whitespace-after:1 lang:js decode:true\">import { Component } from '@angular\/core';\r\nimport { Platform } from 'ionic-angular';\r\nimport { StatusBar, Splashscreen } from 'ionic-native';\r\n\r\nimport { HomePage } from '..\/pages\/home\/home';\r\nimport { CouchbaseProvider } from \"..\/providers\/couchbase-provider\";\r\n\r\n@Component({\r\n    templateUrl: 'app.html'\r\n})\r\nexport class MyApp {\r\n    rootPage = HomePage;\r\n    constructor(platform: Platform, couchbase: CouchbaseProvider) { \r\n        platform.ready().then(() =&gt; {\r\n            StatusBar.styleDefault(); \r\n            Splashscreen.hide();\r\n        });\r\n    }\r\n}<\/pre>\n<p>No c\u00f3digo acima, importamos o provedor e o injetamos no <code>construtor<\/code> m\u00e9todo. Isso ser\u00e1 acionado antes que a primeira p\u00e1gina seja carregada, abrindo o banco de dados, criando a exibi\u00e7\u00e3o e iniciando o ouvinte.<\/p>\n<p>Daqui em diante, passaremos nosso tempo na primeira e \u00fanica p\u00e1gina do aplicativo. Isso significa que passaremos nosso tempo na p\u00e1gina <strong>src\/pages\/home\/home.ts<\/strong> e <strong>src\/pages\/home\/home.html<\/strong> arquivos.<\/p>\n<p>Abra o arquivo <strong>src\/pages\/home\/home.ts<\/strong> e inclua o seguinte c\u00f3digo:<\/p>\n<pre><code>import { Component, NgZone } from '@angular\/core';\r\nimport { NavController, AlertController } from 'ionic-angular';\r\nimport { CouchbaseProvider } from \"..\/..\/providers\/couchbase-provider\";\r\n\r\n@Component({\r\n    selector: 'page-home',\r\n    templateUrl: 'home.html'\r\n})\r\nexport class HomePage {\r\n\r\n    public items: Array;\r\n\r\n    public constructor(public navCtrl: NavController, public alertCtrl: AlertController, public couchbase: CouchbaseProvider, public zone: NgZone) {\r\n        this.items = [];\r\n    }\r\n\r\n    public ionViewDidEnter() { }\r\n\r\n    public refresh() { }\r\n\r\n    public add() { }\r\n\r\n}<\/code><\/pre>\n<p>Vamos detalhar o que isso significa e adicionar cada um dos m\u00e9todos, um por um.<\/p>\n<p>Voc\u00ea pode ver que estamos importando o <code>Provedor do Couchbase<\/code> juntamente com outros componentes. Exploraremos o que cada um deles significa quando chegarmos l\u00e1.<\/p>\n<p>O <code>itens<\/code> que \u00e9 p\u00fablico, manter\u00e1 todos os nossos itens que ser\u00e3o apresentados na interface do usu\u00e1rio, por isso \u00e9 p\u00fablico. A matriz <code>construtor<\/code> tem muitas inje\u00e7\u00f5es para cada um dos componentes que planejamos usar. \u00c9 tamb\u00e9m onde inicializamos nossa matriz p\u00fablica.<\/p>\n<p>Nunca \u00e9 aconselh\u00e1vel carregar dados no <code>construtor<\/code> e \u00e9 por isso que temos o m\u00e9todo <code>ionViewDidEnter<\/code> m\u00e9todo. \u00c9 nesse m\u00e9todo que ocorre a maior parte do trabalho pesado:<\/p>\n<pre class=\"whitespace-after:1 lang:js decode:true\">public ionViewDidEnter() {\r\n    setTimeout(() =&gt; {\r\n        this.couchbase.getChangeListener().subscribe(data =&gt; {\r\n            for(let i = 0; i &lt; data.length; i++) {\r\n                if(!data[i].hasOwnProperty(\"deleted\") &amp;&amp; data[i].id.indexOf(\"_design\") === -1) {\r\n                    this.couchbase.getDatabase().getDocument(data[i].id).then(result =&gt; {\r\n                        if(result.type === \"list\") {\r\n                            this.zone.run(() =&gt; {\r\n                                this.items.push(result);\r\n                            });\r\n                        }\r\n                    });\r\n                }\r\n            }\r\n        });\r\n        this.refresh();\r\n    }, 100);\r\n}<\/pre>\n<p>Primeiro, voc\u00ea notar\u00e1 o tempo limite. Estamos trabalhando com muitos componentes ass\u00edncronos, especificamente o componente Couchbase. Muitas vezes, h\u00e1 uma condi\u00e7\u00e3o de corrida em que o banco de dados n\u00e3o estar\u00e1 pronto a tempo de ser usado. Adicionar um simples timeout de 100 ms \u00e9 mais do que suficiente para fazer a bola rolar. H\u00e1 outras maneiras de fazer isso, mas prefiro o timeout.<\/p>\n<p>Quando a p\u00e1gina for carregada, queremos nos inscrever em nosso ouvinte que foi criado no provedor. Faremos um loop de todos os dados emitidos. Neste exemplo espec\u00edfico, estamos ignorando as exclus\u00f5es e tratando as altera\u00e7\u00f5es e adi\u00e7\u00f5es da mesma forma. Em seu aplicativo, talvez voc\u00ea queira adicionar uma l\u00f3gica mais espec\u00edfica. Basicamente, estou dizendo que, desde que a altera\u00e7\u00e3o n\u00e3o tenha sido uma exclus\u00e3o, pegaremos a chave que foi alterada e faremos uma pesquisa no documento. Se o documento for um de nossos documentos de tarefas, queremos adicion\u00e1-lo \u00e0 matriz p\u00fablica.<\/p>\n<p>Ent\u00e3o, o que est\u00e1 acontecendo com o <code>zona<\/code> coisas? Os emissores podem ficar estranhos, portanto, quando recebemos um evento, queremos atualizar a zona do Angular 2. Voc\u00ea pode achar que isso n\u00e3o \u00e9 necess\u00e1rio, mas se a interface do usu\u00e1rio n\u00e3o for atualizada com as altera\u00e7\u00f5es, n\u00e3o ter o <code>zona<\/code> \u00e9 por isso.<\/p>\n<p>Depois que o ouvinte de altera\u00e7\u00f5es tiver sido criado, queremos consultar o banco de dados como ele se encontra no momento. \u00c9 aqui que o <code>atualizar<\/code> entra em a\u00e7\u00e3o:<\/p>\n<pre class=\"whitespace-after:1 lang:js decode:true\">public refresh() {\r\n    this.couchbase.getDatabase().queryView(\"_design\/todo\", \"items\", {}).then(result =&gt; {\r\n        this.items = [];\r\n        for(var i = 0; i &lt; result.rows.length; i++) { this.items.push(result.rows[i].value); } }, error =&gt; {\r\n        console.error(\"ERROR: \" + JSON.stringify(error));\r\n    });\r\n}<\/pre>\n<p>O <code>atualizar<\/code> consultar\u00e1 nossa exibi\u00e7\u00e3o e adicionar\u00e1 cada um dos itens resultantes \u00e0 nossa matriz p\u00fablica. S\u00f3 precisamos consultar uma vez, porque as altera\u00e7\u00f5es que chegarem ser\u00e3o automaticamente adicionadas para n\u00f3s, por conveni\u00eancia.<\/p>\n<p>O <code>adicionar<\/code> \u00e9 o m\u00e9todo final desta p\u00e1gina do Ionic 2:<\/p>\n<pre class=\"whitespace-after:1 lang:js decode:true\">public add() {\r\n    let prompt = this.alertCtrl.create({\r\n        title: 'Todo Items',\r\n        message: \"Add a new item to the todo list\",\r\n        inputs: [\r\n            {\r\n                name: 'title',\r\n                placeholder: 'Title'\r\n            },\r\n        ],\r\n        buttons: [\r\n            {\r\n                text: 'Cancel',\r\n                handler: data =&gt; {}\r\n            },\r\n            {\r\n                text: 'Save',\r\n                handler: data =&gt; {\r\n                    this.couchbase.getDatabase().createDocument({type: \"list\", title: data.title});\r\n                }\r\n            }\r\n        ]\r\n    });\r\n    prompt.present();\r\n}<\/pre>\n<p>Quando executado, um prompt ser\u00e1 exibido. Quando o usu\u00e1rio inserir informa\u00e7\u00f5es no prompt, elas ser\u00e3o salvas como um documento no Couchbase. O ouvinte de altera\u00e7\u00f5es pegar\u00e1 essa altera\u00e7\u00e3o local e a adicionar\u00e1 \u00e0 lista.<\/p>\n<p>A interface de usu\u00e1rio simples por tr\u00e1s desse aplicativo, encontrada na se\u00e7\u00e3o <strong>src\/pages\/home\/home.html<\/strong> tem a seguinte apar\u00eancia:<\/p>\n<pre class=\"lang:default decode:true\">&lt;ion-header&gt;\r\n    &lt;ion-navbar&gt;\r\n        &lt;ion-title&gt;\r\n            Couchbase w\/ Ionic 2\r\n        &lt;\/ion-title&gt;\r\n        &lt;ion-buttons end&gt;\r\n            &lt;button ion-button icon-only (click)=\"add()\"&gt;\r\n                &lt;ion-icon name=\"add\"&gt;&lt;\/ion-icon&gt;\r\n            &lt;\/button&gt;\r\n        &lt;\/ion-buttons&gt;\r\n    &lt;\/ion-navbar&gt;\r\n&lt;\/ion-header&gt;\r\n\r\n&lt;ion-content padding&gt;\r\n    &lt;ion-list&gt;\r\n        &lt;ion-item *ngFor=\"let item of items\"&gt;\r\n            {{ item.title }}\r\n        &lt;\/ion-item&gt;\r\n    &lt;\/ion-list&gt;\r\n&lt;\/ion-content&gt;<\/pre>\n<p>A interface do usu\u00e1rio tem uma barra de a\u00e7\u00e3o com um bot\u00e3o para exibir o prompt. O conte\u00fado principal \u00e9 uma exibi\u00e7\u00e3o de lista em que percorremos a matriz p\u00fablica do arquivo TypeScript.<\/p>\n<h2 id=\"synchronization-between-devices-and-platforms\">Sincroniza\u00e7\u00e3o entre dispositivos e plataformas<\/h2>\n<p>At\u00e9 agora, tudo era local em um \u00fanico dispositivo. Nada do que adicionamos at\u00e9 agora foi respons\u00e1vel pela sincroniza\u00e7\u00e3o com o Couchbase Sync Gateway ou com outros dispositivos. No entanto, adicionar suporte \u00e0 sincroniza\u00e7\u00e3o n\u00e3o requer quase nenhum esfor\u00e7o.<\/p>\n<p>Abra o arquivo <strong>src\/providers\/couchbase-provider.ts<\/strong> e inclua a seguinte linha ap\u00f3s abrir o banco de dados:<\/p>\n<pre><code>this.database.sync(\"https:\/\/192.168.57.1:4984\/example\", true);<\/code><\/pre>\n<p>Obviamente, troque o nome do host e o nome do banco de dados pelo nome da inst\u00e2ncia remota do Sync Gateway. Agora seu aplicativo ser\u00e1 sincronizado continuamente. N\u00e3o \u00e9 incr\u00edvel que uma linha de c\u00f3digo tenha nos dado suporte \u00e0 sincroniza\u00e7\u00e3o?<\/p>\n<p>Se voc\u00ea deseja ativar uma inst\u00e2ncia simples do Sync Gateway, aqui e agora, crie o seguinte <strong>sync-gateway-config.json<\/strong> file:<\/p>\n<pre><code>{\r\n    \"log\":[\"CRUD+\", \"REST+\", \"Changes+\", \"Attach+\"],\r\n    \"databases\": {\r\n        \"example\": {\r\n            \"server\":\"walrus:\",\r\n            \"sync\":`\r\n                function (doc) {\r\n                    channel (doc.channels);\r\n                }\r\n            `,\r\n            \"users\": {\r\n                \"GUEST\": {\r\n                    \"disabled\": false,\r\n                    \"admin_channels\": [\"*\"]\r\n                }\r\n            }\r\n        }\r\n    }\r\n}<\/code><\/pre>\n<p>Quando voc\u00ea iniciar o Sync Gateway, aponte-o para esse arquivo de configura\u00e7\u00e3o espec\u00edfico. Atualize seu <code>sincroniza\u00e7\u00e3o<\/code> no aplicativo Ionic 2 para corresponder ao host e ao banco de dados.<\/p>\n<h2 id=\"taking-the-finished-project-for-a-test-drive\">Testando o projeto finalizado<\/h2>\n<p>Entendo que este guia tenha sido um pouco longo. Eu fui em frente e publiquei um <a href=\"https:\/\/github.com\/couchbaselabs\/todolite-ionic2\">projeto de amostra<\/a> no GitHub que voc\u00ea pode executar e revisar para complementar este tutorial.<\/p>\n<p>Clone o projeto executando-o:<\/p>\n<pre><code>git clone https:\/\/github.com\/couchbaselabs\/todolite-ionic2<\/code><\/pre>\n<p>Com o download do projeto, precisamos restaurar as depend\u00eancias, os plug-ins e as plataformas do projeto. Execute o seguinte para restaurar essas depend\u00eancias:<\/p>\n<pre><code>npm install\r\nionic state restore<\/code><\/pre>\n<p>Agora voc\u00ea pode continuar a executar o aplicativo em seu dispositivo ou simulador. S\u00f3 n\u00e3o se esque\u00e7a de executar o Couchbase Sync Gateway e atualizar o arquivo <code>sincroniza\u00e7\u00e3o<\/code> para refletir o m\u00e9todo de sua configura\u00e7\u00e3o remota.<\/p>\n<h2 id=\"conclusion\">Conclus\u00e3o<\/h2>\n<p>Voc\u00ea acabou de ver como criar um aplicativo m\u00f3vel h\u00edbrido de plataforma cruzada para iOS e Android com o <a href=\"https:\/\/www.ionicframework.com\">I\u00f4nico 2<\/a> que usa o Couchbase Mobile. Esse \u00e9 um passo \u00e0 frente e uma revis\u00e3o do meu <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/using-couchbase-in-your-ionic-framework-application-part-1\/\">Artigo anterior<\/a> que demonstrou o Ionic Framework 1.0 e o Couchbase Mobile.<\/p>","protected":false},"excerpt":{"rendered":"<p>Last year I wrote about using Couchbase Mobile in an Ionic Framework mobile application. Back then we were using Ionic Framework 1.0 and AngularJS 1.0. Technology has changed over the months and we&#8217;ve moved from what seems like ancient frameworks [&hellip;]<\/p>","protected":false},"author":63,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,1810,9327],"tags":[1535,1773,1534,1543],"ppma_author":[9032],"class_list":["post-2456","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-couchbase-mobile","category-javascript","tag-apache-cordova","tag-ionic-2","tag-ionic-framework","tag-javascript"],"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>Couchbase Mobile in an Android and iOS Ionic 2 applicat<\/title>\n<meta name=\"description\" content=\"This blog covers how to create a cross-platform iOS and Android hybrid mobile application with Ionic 2 that uses 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\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Data Synchronization with Couchbase in Ionic 2 Hybrid Mobile Apps\" \/>\n<meta property=\"og:description\" content=\"This blog covers how to create a cross-platform iOS and Android hybrid mobile application with Ionic 2 that uses Couchbase Mobile.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/thepolyglotdeveloper\" \/>\n<meta property=\"article:published_time\" content=\"2016-12-15T15:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:15:37+00:00\" \/>\n<meta name=\"author\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Data Synchronization with Couchbase in Ionic 2 Hybrid Mobile Apps\",\"datePublished\":\"2016-12-15T15:00:00+00:00\",\"dateModified\":\"2025-06-14T03:15:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/\"},\"wordCount\":1856,\"commentCount\":17,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"apache cordova\",\"ionic 2\",\"ionic framework\",\"javascript\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Couchbase Mobile\",\"JavaScript\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/\",\"name\":\"Couchbase Mobile in an Android and iOS Ionic 2 applicat\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2016-12-15T15:00:00+00:00\",\"dateModified\":\"2025-06-14T03:15:37+00:00\",\"description\":\"This blog covers how to create a cross-platform iOS and Android hybrid mobile application with Ionic 2 that uses Couchbase Mobile.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#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\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Data Synchronization with Couchbase in Ionic 2 Hybrid Mobile Apps\"}]},{\"@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\/bb545ebe83bb2d12f91095811d0a72e1\",\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy, Developer Advocate, Couchbase\"},\"description\":\"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.\",\"sameAs\":[\"https:\/\/www.thepolyglotdeveloper.com\",\"https:\/\/www.facebook.com\/thepolyglotdeveloper\",\"https:\/\/x.com\/nraboy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/nic-raboy-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Couchbase Mobile in an Android and iOS Ionic 2 applicat","description":"Este blog aborda como criar um aplicativo m\u00f3vel h\u00edbrido multiplataforma para iOS e Android com o Ionic 2 que usa o 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\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/","og_locale":"pt_BR","og_type":"article","og_title":"Data Synchronization with Couchbase in Ionic 2 Hybrid Mobile Apps","og_description":"This blog covers how to create a cross-platform iOS and Android hybrid mobile application with Ionic 2 that uses Couchbase Mobile.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2016-12-15T15:00:00+00:00","article_modified_time":"2025-06-14T03:15:37+00:00","author":"Nic Raboy, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_misc":{"Written by":"Nic Raboy, Developer Advocate, Couchbase","Est. reading time":"11 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Data Synchronization with Couchbase in Ionic 2 Hybrid Mobile Apps","datePublished":"2016-12-15T15:00:00+00:00","dateModified":"2025-06-14T03:15:37+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/"},"wordCount":1856,"commentCount":17,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["apache cordova","ionic 2","ionic framework","javascript"],"articleSection":["Best Practices and Tutorials","Couchbase Mobile","JavaScript"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/","url":"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/","name":"Couchbase Mobile in an Android and iOS Ionic 2 applicat","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2016-12-15T15:00:00+00:00","dateModified":"2025-06-14T03:15:37+00:00","description":"Este blog aborda como criar um aplicativo m\u00f3vel h\u00edbrido multiplataforma para iOS e Android com o Ionic 2 que usa o Couchbase Mobile.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#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\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Data Synchronization with Couchbase in Ionic 2 Hybrid Mobile Apps"}]},{"@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\/bb545ebe83bb2d12f91095811d0a72e1","name":"Nic Raboy, defensor dos desenvolvedores, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354","url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","caption":"Nic Raboy, Developer Advocate, Couchbase"},"description":"Nic Raboy \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/nic-raboy-2\/"}]}},"authors":[{"term_id":9032,"user_id":63,"is_guest":0,"slug":"nic-raboy-2","display_name":"Nic Raboy, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","author_category":"","last_name":"Raboy","first_name":"Nic","job_title":"","user_url":"https:\/\/www.thepolyglotdeveloper.com","description":"Nic Raboy \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2456","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\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=2456"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2456\/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=2456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2456"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=2456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}