{"id":2480,"date":"2017-01-01T15:00:00","date_gmt":"2017-01-01T15:00:00","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2480"},"modified":"2025-06-13T20:15:36","modified_gmt":"2025-06-14T03:15:36","slug":"syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/","title":{"rendered":"Sincroniza\u00e7\u00e3o com o Couchbase em um aplicativo Ionic 2 usando o PouchDB"},"content":{"rendered":"<p>N\u00e3o faz muito tempo, escrevi sobre o uso de <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/\">Couchbase em um aplicativo Ionic 2<\/a>. No exemplo anterior, vimos como usar o Couchbase Lite e a API RESTful para salvar dados e trabalhar com o Couchbase Sync Gateway. Embora essa seja a abordagem preferida, ela n\u00e3o \u00e9 a \u00fanica.<\/p>\n<p>H\u00e1 uma excelente biblioteca JavaScript chamada <a href=\"https:\/\/pouchdb.com\/\">PouchDB<\/a> que pode realmente se conectar ao Couchbase Sync Gateway, tirando o Couchbase Lite da equa\u00e7\u00e3o. Isso significa que o PouchDB pode ser usado com o Ionic 2 para sincronizar dados entre o Couchbase Server e qualquer aplicativo que tenha sido criado.<\/p>\n<p>Ent\u00e3o, como podemos fazer isso acontecer?<\/p>\n<h2 id=\"the-requirements\">Os requisitos<\/h2>\n<p>Se voc\u00ea viu o tutorial anterior, os requisitos aqui n\u00e3o ser\u00e3o diferentes. Eles s\u00e3o os seguintes:<\/p>\n<ul>\n<li>Node.js 4.0+<\/li>\n<li><a href=\"https:\/\/www.ionicframework.com\">Estrutura i\u00f4nica<\/a> 2.0<\/li>\n<li>Gateway de sincroniza\u00e7\u00e3o do Couchbase<\/li>\n<li>Android SDK para Android e Xcode para iOS<\/li>\n<\/ul>\n<p>A CLI do Ionic Framework 2.0 \u00e9 usada para criar e desenvolver aplicativos. Ele usa o Node Package Manager (NPM) encontrado com o Node.js para baixar todas as depend\u00eancias. N\u00e3o sincronizaremos com o Couchbase Server neste exemplo, mas ainda usaremos o Couchbase Sync Gateway. O plano aqui \u00e9 usar a op\u00e7\u00e3o na mem\u00f3ria que o Sync Gateway tem para prototipagem. Incluir o Couchbase Server n\u00e3o \u00e9 dif\u00edcil depois disso.<\/p>\n<h2 id=\"preparing-couchbase-sync-gateway\">Preparando o Couchbase Sync Gateway<\/h2>\n<p>O Couchbase Sync Gateway lida com toda a orquestra\u00e7\u00e3o de dados entre dispositivos, plataformas e o Couchbase Server. Isso inclui todas as permiss\u00f5es de leitura e grava\u00e7\u00e3o. Por isso, ele precisa ter sua pr\u00f3pria configura\u00e7\u00e3o com base nas necessidades de seu aplicativo.<\/p>\n<p>Veja a configura\u00e7\u00e3o a seguir, por exemplo:<\/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    \"CORS\": {\r\n        \"Origin\": [\"https:\/\/localhost:8100\"],\r\n        \"LoginOrigin\": [\"https:\/\/localhost:8100\"],\r\n        \"Headers\": [\"Content-Type\"],\r\n        \"MaxAge\": 17280000\r\n    }\r\n}<\/code><\/pre>\n<p>A configura\u00e7\u00e3o acima cria um banco de dados chamado <strong>exemplo<\/strong> sem regras em termos de canaliza\u00e7\u00e3o de dados. Isso significa que todos os dispositivos poder\u00e3o ler e gravar. Suas necessidades podem ser diferentes.<\/p>\n<p>Na parte inferior da configura\u00e7\u00e3o, h\u00e1 informa\u00e7\u00f5es sobre o compartilhamento de recursos entre origens (CORS). A parte inferior n\u00e3o \u00e9 necess\u00e1ria, a menos que voc\u00ea planeje usar recursos como <code>servi\u00e7o i\u00f4nico<\/code>. A tentativa de acessar o Sync Gateway a partir do mesmo host, mas de uma porta diferente, gerar\u00e1 erros de JavaScript. A adi\u00e7\u00e3o do CORS evitar\u00e1 isso. Mais uma vez, isso ocorre somente se voc\u00ea desejar servir o aplicativo em seu navegador da Web. A execu\u00e7\u00e3o do aplicativo em seu dispositivo n\u00e3o apresentar\u00e1 problemas.<\/p>\n<h2 id=\"creating-an-ionic-framework-with-pouchdb-application\">Cria\u00e7\u00e3o de um aplicativo Ionic Framework com PouchDB<\/h2>\n<p>O aplicativo que criaremos ser\u00e1 semelhante ao que criamos anteriormente com o Couchbase Lite e o Ionic 2. Criaremos um aplicativo simples de lista de tarefas que sincroniza os itens entre dispositivos.<\/p>\n<div class=\"figure\"><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2017\/january\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/pouchdb-ionic2-cbmobile.gif\" alt=\"Couchbase with Ionic 2 and PouchDB\" \/><\/div>\n<p>Este \u00e9 um aplicativo de p\u00e1gina \u00fanica, mas abrange todas as pr\u00e1ticas recomendadas necess\u00e1rias do Ionic 2 e do Angular 2. Para criar esse projeto, execute o seguinte em seu prompt de comando (Windows) ou terminal (Mac e Linux):<\/p>\n<pre><code>ionic start PouchDBProject blank --v2\r\ncd PouchDBProject\r\nionic platform add ios\r\nionic platform add android<\/code><\/pre>\n<p>Os comandos acima criar\u00e3o um novo projeto Ionic 2 que usa Angular 2 e TypeScript. Embora eu tenha adicionado as plataformas de compila\u00e7\u00e3o Android e iOS, voc\u00ea n\u00e3o poder\u00e1 compilar para iOS a menos que esteja usando um Mac com o Xcode instalado.<\/p>\n<p>Como este projeto usar\u00e1 <a href=\"https:\/\/pouchdb.com\/\">PouchDB<\/a>ele precisa ser instalado em nosso projeto. Isso pode ser feito executando o seguinte comando:<\/p>\n<pre><code>npm install pouchdb --save<\/code><\/pre>\n<p>O PouchDB \u00e9 um projeto JavaScript e n\u00e3o tem suporte adequado para TypeScript. Isso n\u00e3o \u00e9 um problema, pois podemos contornar o obst\u00e1culo da falta de defini\u00e7\u00f5es de tipos. No entanto, precisaremos obter defini\u00e7\u00f5es de tipo para outra biblioteca que carregar\u00e1 o plug-in.<\/p>\n<p>Na linha de comando, execute o seguinte:<\/p>\n<pre><code>npm install @type\/node --save<\/code><\/pre>\n<p>A instala\u00e7\u00e3o das defini\u00e7\u00f5es de tipo do Node.js nos permitir\u00e1 usar o <code>exigir<\/code> que \u00e9 essencial ao importar depend\u00eancias de JavaScript.<\/p>\n<p>H\u00e1 mais uma depend\u00eancia de JavaScript para o nosso projeto, mas, desta vez, n\u00e3o precisamos nos preocupar com o fato de as defini\u00e7\u00f5es de tipo n\u00e3o existirem. Precisamos instalar uma biblioteca para gerar valores de identifica\u00e7\u00e3o exclusivos que representar\u00e3o nossas chaves de documento. Essa biblioteca pode ser instalada por meio do seguinte comando:<\/p>\n<pre><code>npm install uuid @type\/uuid --save<\/code><\/pre>\n<p>O comando acima instalar\u00e1 a biblioteca e suas defini\u00e7\u00f5es de tipo para o TypeScript.<\/p>\n<p>Neste ponto, podemos nos concentrar no desenvolvimento do nosso aplicativo!<\/p>\n<h3 id=\"developing-the-angular-2-shared-provider\">Desenvolvendo o provedor compartilhado do Angular 2<\/h3>\n<p>\u00c9 uma boa pr\u00e1tica em qualquer aplicativo Angular 2 manter a atividade relacionada ao banco de dados separada no que \u00e9 conhecido como provedor compartilhado ou servi\u00e7o compartilhado. Isso nos permite ter uma inst\u00e2ncia de banco de dados \u00fanica e manter nosso c\u00f3digo de banco de dados fora da l\u00f3gica da p\u00e1gina.<\/p>\n<p>Para criar um provedor no Ionic 2, execute o seguinte comando:<\/p>\n<pre><code>ionic g provider pouchdb-provider<\/code><\/pre>\n<p>O comando acima deve criar um arquivo em <strong>src\/providers\/pouchdb-provider.ts<\/strong> com o qual podemos trabalhar. Abra esse novo arquivo e inclua o seguinte c\u00f3digo:<\/p>\n<pre><code>import { Injectable, EventEmitter } from '@angular\/core';\r\nvar PouchDB = require(\"pouchdb\");\r\n\r\n@Injectable()\r\nexport class PouchDBProvider {\r\n\r\n    private isInstantiated: boolean;\r\n    private database: any;\r\n    private listener: EventEmitter = new EventEmitter();\r\n\r\n    public constructor() { }\r\n\r\n    public fetch() { }\r\n\r\n    public get(id: string) { }\r\n\r\n    public put(document: any, id: string) { }\r\n\r\n    public sync(remote: string) { }\r\n\r\n    public getChangeListener() { }\r\n\r\n}<\/code><\/pre>\n<p>Antes de come\u00e7armos a preencher cada um dos m\u00e9todos, vamos detalhar o que temos at\u00e9 o momento.<\/p>\n<p>Esse provedor poder\u00e1 ser injetado em cada uma das p\u00e1ginas que desejamos usar. Como o PouchDB nos permite sincronizar altera\u00e7\u00f5es, queremos poder emitir essas altera\u00e7\u00f5es e assin\u00e1-las, por isso a necessidade do provedor <code>Emissor de eventos<\/code> importar. A biblioteca do PouchDB \u00e9 importada como o JavaScript padr\u00e3o.<\/p>\n<p>Queremos manter apenas uma inst\u00e2ncia do banco de dados aberta e podemos fazer isso usando um <code>isInstantiated<\/code> vari\u00e1vel. Isso \u00e9 feito na vari\u00e1vel <code>construtor<\/code> m\u00e9todo assim:<\/p>\n<pre><code>public constructor() {\r\n    if(!this.isInstantiated) {\r\n        this.database = new PouchDB(\"nraboy\");\r\n        this.isInstantiated = true;\r\n    }\r\n}<\/code><\/pre>\n<p>Com um banco de dados aberto, queremos poder trabalhar com os dados. O PouchDB tem suas pr\u00f3prias APIs para trabalhar com dados, mas, como se trata de JavaScript b\u00e1sico, algumas coisas devem ser aprimoradas em nosso provedor para torn\u00e1-lo mais amig\u00e1vel ao Angular 2.<\/p>\n<pre><code>public fetch() {\r\n    return this.database.allDocs({include_docs: true});\r\n}<\/code><\/pre>\n<p>A obten\u00e7\u00e3o de todos os dados pode ser feita usando o <code>todos os documentos<\/code> no PouchDB. Ao incluir o m\u00e9todo <code>incluir_docs<\/code> os dados do documento s\u00e3o inclu\u00eddos em vez de apenas os valores de id.<\/p>\n<pre><code>public get(id: string) {\r\n    return this.database.get(id);\r\n}<\/code><\/pre>\n<p>Se voc\u00ea souber o ID do documento que est\u00e1 procurando, poder\u00e1 fazer uma pesquisa diretamente em vez de consultar todos os documentos. O salvamento de documentos \u00e9 o ponto em que as coisas podem ficar um pouco confusas:<\/p>\n<pre><code>public put(document: any, id: string) {\r\n    document._id = id;\r\n    return this.get(id).then(result =&gt; {\r\n        document._rev = result._rev;\r\n        return this.database.put(document);\r\n    }, error =&gt; {\r\n        if(error.status == \"404\") {\r\n            return this.database.put(document);\r\n        } else {\r\n            return new Promise((resolve, reject) =&gt; {\r\n                reject(error);\r\n            });\r\n        }\r\n    });\r\n}<\/code><\/pre>\n<p>No exemplo acima <code>colocar<\/code> temos uma maneira de criar ou atualizar um documento. Os documentos que n\u00e3o t\u00eam revis\u00e3o s\u00e3o criados, caso contr\u00e1rio, s\u00e3o atualizados. Isso \u00e9 poss\u00edvel fazendo primeiro uma pesquisa em um documento pelo seu ID. Se o documento existir, use a revis\u00e3o e atualize-o; caso contr\u00e1rio, crie-o.<\/p>\n<pre><code>public sync(remote: string) {\r\n    let remoteDatabase = new PouchDB(remote);\r\n    this.database.sync(remoteDatabase, {\r\n        live: true\r\n    }).on('change', change =&gt; {\r\n        this.listener.emit(change);\r\n    }).on('error', error =&gt; {\r\n        console.error(JSON.stringify(error));\r\n    });\r\n}<\/code><\/pre>\n<p>Sem a sincroniza\u00e7\u00e3o, voc\u00ea n\u00e3o est\u00e1 tecnicamente usando o Couchbase em sua pilha. Al\u00e9m disso, h\u00e1 solu\u00e7\u00f5es muito melhores para dados do que o PouchDB se voc\u00ea estiver procurando apenas um banco de dados local. Dito isso, as informa\u00e7\u00f5es acima <code>sincroniza\u00e7\u00e3o<\/code> permitir\u00e1 que voc\u00ea se conecte a um banco de dados remoto. Nosso banco de dados remoto \u00e9, na verdade, uma inst\u00e2ncia do Sync Gateway em execu\u00e7\u00e3o. Estamos optando por fazer uma sincroniza\u00e7\u00e3o bidirecional com o Sync Gateway e emitindo as altera\u00e7\u00f5es para a inst\u00e2ncia <code>Emissor de eventos<\/code> no Angular 2.<\/p>\n<pre><code>public getChangeListener() {\r\n    return this.listener;\r\n}<\/code><\/pre>\n<p>Quando quisermos assinar essas altera\u00e7\u00f5es, devemos primeiro obter uma c\u00f3pia do ouvinte que as est\u00e1 emitindo.<\/p>\n<p>Neste ponto, o provedor do Angular 2 est\u00e1 completo, mas n\u00e3o est\u00e1 pronto para ser usado. Ele precisa ser adicionado \u00e0 se\u00e7\u00e3o <code>@NgModule<\/code> encontrado no bloco <strong>src\/app\/app.module.ts<\/strong> arquivo. O arquivo seria parecido com o seguinte:<\/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\nimport { PouchDBProvider } from \"..\/providers\/pouchdb-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}, PouchDBProvider]\r\n})\r\nexport class AppModule {}<\/code><\/pre>\n<p>Observe como o provedor foi importado e, em seguida, adicionado ao <code>provedores<\/code> array. Agora ele pode ser usado em cada p\u00e1gina do nosso aplicativo.<\/p>\n<h3 id=\"adding-pouchdb-logic-for-saving-and-syncing\">Adi\u00e7\u00e3o da l\u00f3gica do PouchDB para salvar e sincronizar<\/h3>\n<p>O restante do nosso aplicativo \u00e9, na verdade, bastante simples, agora que estabelecemos a base para o nosso <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/resources\/concepts\/data-platforms\/\">camada de dados<\/a>. Lembre-se de que este \u00e9 um aplicativo muito simples, mas altamente orientado por dados.<\/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 { PouchDBProvider } from \"..\/..\/providers\/pouchdb-provider\";\r\nimport * as Uuid from \"uuid\";\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, private database: PouchDBProvider, private zone: NgZone) {\r\n        this.items = [];\r\n    }\r\n\r\n    public ionViewDidEnter() { }\r\n\r\n    public insert() { }\r\n\r\n}<\/code><\/pre>\n<p>No c\u00f3digo acima, estamos importando v\u00e1rios componentes do Ionic e do Angular 2, bem como nosso provedor PouchDB e a biblioteca UUID. Muitos desses componentes s\u00e3o injetados na se\u00e7\u00e3o <code>construtor<\/code> m\u00e9todo. O <code>construtor<\/code> tamb\u00e9m inicializa nossa matriz p\u00fablica que ser\u00e1 vinculada \u00e0 interface do usu\u00e1rio. Essa matriz conter\u00e1 os dados que sincronizamos com o PouchDB.<\/p>\n<p>Embora possamos inicializar nossas vari\u00e1veis no <code>construtor<\/code> nunca \u00e9 uma boa ideia carregar dados neles no m\u00e9todo <code>construtor<\/code> m\u00e9todo. Em vez disso, devemos usar o m\u00e9todo Ionic <code>ionViewDidEnter<\/code> m\u00e9todo:<\/p>\n<pre><code>public ionViewDidEnter() {\r\n    this.database.sync(\"https:\/\/192.168.57.1:4984\/example\");\r\n    this.database.getChangeListener().subscribe(data =&gt; {\r\n        for(let i = 0; i &lt; data.change.docs.length; i++) { this.zone.run(() =&gt; {\r\n                this.items.push(data.change.docs[i]);\r\n            });\r\n        }\r\n    });\r\n    this.database.fetch().then(result =&gt; {\r\n        this.items = [];\r\n        for(let i = 0; i &lt; result.rows.length; i++) { this.items.push(result.rows[i].doc); } }, error =&gt; {\r\n        console.error(error);\r\n    });\r\n}<\/code><\/pre>\n<p>No exemplo acima <code>ionViewDidEnter<\/code> estamos iniciando a sincroniza\u00e7\u00e3o bidirecional com o PouchDB e o Couchbase Sync Gateway. O nome do host \u00e9 o da minha inst\u00e2ncia do Couchbase Sync Gateway em execu\u00e7\u00e3o no momento. O banco de dados n\u00e3o precisa corresponder ao meu banco de dados local.<\/p>\n<p>Quando estivermos sincronizando, tamb\u00e9m assinaremos o ouvinte de altera\u00e7\u00f5es. Este \u00e9 um aplicativo simples, portanto, n\u00e3o nos preocuparemos em alterar ou excluir dados, apenas em adicionar dados. Os ouvintes podem ser um pouco duvidosos no Angular 2, pois h\u00e1 uma desconex\u00e3o entre a interface do usu\u00e1rio e os dados. Essa desconex\u00e3o pode ser corrigida adicionando os dados do listener em um <code>zone.run<\/code> m\u00e9todo.<\/p>\n<p>Com o aplicativo assinando as altera\u00e7\u00f5es, precisamos fazer uma primeira consulta dos dados quando o aplicativo for aberto. Queremos <code>buscar<\/code> todos os dados e adicion\u00e1-los \u00e0 nossa matriz p\u00fablica.<\/p>\n<p>O \u00faltimo m\u00e9todo que temos \u00e9 o <code>inserir<\/code> e \u00e9 principalmente orientado pelo Ionic:<\/p>\n<pre><code>public insert() {\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.database.put({type: \"list\", title: data.title}, Uuid.v4());\r\n                }\r\n            }\r\n        ]\r\n    });\r\n    prompt.present();\r\n}<\/code><\/pre>\n<p>Aqui criamos um pop-up de prompt. Quando o bot\u00e3o Salvar \u00e9 pressionado, o texto no formul\u00e1rio \u00e9 salvo no PouchDB. O ID do documento \u00e9 gerado exclusivamente com a biblioteca UUID.<\/p>\n<p>Ent\u00e3o, qual \u00e9 a apar\u00eancia de nossa interface do usu\u00e1rio?<\/p>\n<h3 id=\"creating-a-simple-ui-with-html\">Cria\u00e7\u00e3o de uma interface de usu\u00e1rio simples com HTML<\/h3>\n<p>A interface do usu\u00e1rio \u00e9 a parte mais f\u00e1cil porque o aplicativo \u00e9 muito simples. Abra a se\u00e7\u00e3o <strong>src\/pages\/home\/home.html<\/strong> e inclua a seguinte marca\u00e7\u00e3o HTML:<\/p>\n<pre><code>&lt;ion-header&gt;\r\n    &lt;ion-navbar&gt;\r\n        &lt;ion-title&gt;\r\n            PouchDB 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)=\"insert()\"&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;<\/code><\/pre>\n<p>A interface do usu\u00e1rio tem uma barra de a\u00e7\u00e3o com um bot\u00e3o que, quando pressionado, aciona o <code>inserir<\/code> encontrado em nosso TypeScript. O conte\u00fado principal da interface do usu\u00e1rio \u00e9 uma lista que percorre a matriz p\u00fablica imprimindo cada item na tela.<\/p>\n<h2 id=\"taking-the-project-for-a-test-run\">Execu\u00e7\u00e3o do projeto para teste<\/h2>\n<p>Passamos por muitos conceitos e muito c\u00f3digo. Para facilitar a vida, eu <a href=\"https:\/\/github.com\/couchbaselabs\/todolite-ionic2-pouchdb\">fez o upload de um projeto funcional<\/a> no GitHub, que voc\u00ea pode baixar e testar por si mesmo.<\/p>\n<p>Com o download do projeto, execute os seguintes comandos para restaurar as depend\u00eancias, os plug-ins e as plataformas:<\/p>\n<pre><code>npm install\r\nionic state restore<\/code><\/pre>\n<p>Desde que voc\u00ea n\u00e3o se esque\u00e7a de atualizar o <code>sincroniza\u00e7\u00e3o<\/code> encontrado no m\u00e9todo <strong>src\/pages\/home\/home.ts<\/strong> com o host do Sync Gateway, o projeto deve poder ser executado.<\/p>\n<h2 id=\"conclusion\">Conclus\u00e3o<\/h2>\n<p>Voc\u00ea acabou de ver como criar um aplicativo para Android e iOS que sincroniza usando o Ionic 2, o PouchDB e o Couchbase. Esse \u00e9 um m\u00e9todo alternativo ao m\u00e9todo <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps\/\">guia anterior<\/a> que escrevi e que usa o Couchbase Lite.<\/p>","protected":false},"excerpt":{"rendered":"<p>Not too long ago I wrote about using Couchbase in an Ionic 2 application. In the previous example we saw how to use Couchbase Lite and the RESTful API for saving data and working with Couchbase Sync Gateway. While that [&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":[1578,1773,1534,1543,1541],"ppma_author":[9032],"class_list":["post-2480","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-couchbase-mobile","category-javascript","tag-angular-2","tag-ionic-2","tag-ionic-framework","tag-javascript","tag-pouchdb"],"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>Syncing with Couchbase in an Ionic 2 App using PouchDB<\/title>\n<meta name=\"description\" content=\"Learn how to create an Android and iOS application that syncs using Ionic 2, PouchDB, and Couchbase. This is an alternative method to Couchbase Lite.\" \/>\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\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Syncing with Couchbase in an Ionic 2 App using PouchDB\" \/>\n<meta property=\"og:description\" content=\"Learn how to create an Android and iOS application that syncs using Ionic 2, PouchDB, and Couchbase. This is an alternative method to Couchbase Lite.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/\" \/>\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=\"2017-01-01T15:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:15:36+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=\"8 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Syncing with Couchbase in an Ionic 2 App using PouchDB\",\"datePublished\":\"2017-01-01T15:00:00+00:00\",\"dateModified\":\"2025-06-14T03:15:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/\"},\"wordCount\":1680,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"angular 2\",\"ionic 2\",\"ionic framework\",\"javascript\",\"pouchdb\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Couchbase Mobile\",\"JavaScript\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/\",\"name\":\"Syncing with Couchbase in an Ionic 2 App using PouchDB\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2017-01-01T15:00:00+00:00\",\"dateModified\":\"2025-06-14T03:15:36+00:00\",\"description\":\"Learn how to create an Android and iOS application that syncs using Ionic 2, PouchDB, and Couchbase. This is an alternative method to Couchbase Lite.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#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\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Syncing with Couchbase in an Ionic 2 App using PouchDB\"}]},{\"@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":"Sincroniza\u00e7\u00e3o com o Couchbase em um aplicativo Ionic 2 usando o PouchDB","description":"Saiba como criar um aplicativo para Android e iOS que sincroniza usando o Ionic 2, o PouchDB e o Couchbase. Esse \u00e9 um m\u00e9todo alternativo ao Couchbase Lite.","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\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/","og_locale":"pt_BR","og_type":"article","og_title":"Syncing with Couchbase in an Ionic 2 App using PouchDB","og_description":"Learn how to create an Android and iOS application that syncs using Ionic 2, PouchDB, and Couchbase. This is an alternative method to Couchbase Lite.","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2017-01-01T15:00:00+00:00","article_modified_time":"2025-06-14T03:15:36+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":"8 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Syncing with Couchbase in an Ionic 2 App using PouchDB","datePublished":"2017-01-01T15:00:00+00:00","dateModified":"2025-06-14T03:15:36+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/"},"wordCount":1680,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["angular 2","ionic 2","ionic framework","javascript","pouchdb"],"articleSection":["Best Practices and Tutorials","Couchbase Mobile","JavaScript"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/","url":"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/","name":"Sincroniza\u00e7\u00e3o com o Couchbase em um aplicativo Ionic 2 usando o PouchDB","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2017-01-01T15:00:00+00:00","dateModified":"2025-06-14T03:15:36+00:00","description":"Saiba como criar um aplicativo para Android e iOS que sincroniza usando o Ionic 2, o PouchDB e o Couchbase. Esse \u00e9 um m\u00e9todo alternativo ao Couchbase Lite.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#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\/syncing-with-couchbase-in-an-ionic-2-app-using-pouchdb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Syncing with Couchbase in an Ionic 2 App using PouchDB"}]},{"@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\/2480","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=2480"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2480\/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=2480"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2480"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2480"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=2480"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}