No ano passado, escrevi sobre o uso de Couchbase Mobile em um aplicativo móvel do Ionic Framework. Naquela época, usávamos 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ções muito mais modernas.
Com o lançamento do Angular 2 e o Ionic 2 se aproximando da versão estável, achei que seria uma ótima ideia revisitar o que fiz anteriormente e explorar o Couchbase Mobile em um aplicativo Ionic 2 para Android e iOS.
Os requisitos
Para tornar esse projeto possível, precisaremos de alguns itens instalados e disponíveis. Eles são os seguintes:
- Node.js 4.0+
- Estrutura Ionic 2.0
- O Android SDK ou o Xcode
- Gateway de sincronização do Couchbase
O Ionic Framework usa o Node Package Manager (NPM) que vem com o Node.js para lidar com todas as dependências 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ção, precisaremos do Couchbase Sync Gateway instalado e disponível.
Criação de um novo projeto Ionic 2
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á sincronizada entre dispositivos e plataformas, conforme demonstrado na imagem animada abaixo.

Esse é o mesmo aplicativo que vimos no tutorial do Ionic Framework 1.0, bem como em muitos outros tutoriais para celular. É o mesmo aplicativo porque serve como um exemplo muito útil.
Para simplificar, começaremos com um projeto novo. No prompt de comando (Windows) ou no Terminal (Linux e Mac), execute o seguinte:
1 2 3 4 |
iônico iniciar Projeto Couchbase em branco --v2 cd Projeto Couchbase iônico plataforma adicionar ios iônico plataforma adicionar androide |
Os comandos acima criarão um projeto do Ionic Framework 2.0 que usa Angular 2 e TypeScript. Embora eu tenha optado por adicionar as plataformas de compilação iOS e Android, não poderemos compilar para iOS a menos que estejamos usando um Mac com o Xcode instalado.
Esse projeto depende do Plug-in do Couchbase para PhoneGap para funcionar. Não se assuste. Embora o nome diga PhoneGap, ele é, na verdade, apenas um plug-in do Apache Cordova, algo que é muito compatível com o Ionic 2. Para instalar esse plug-in no projeto, execute o seguinte:
1 |
iônico plug-in adicionar https://github.com/couchbaselabs/Couchbase-Lite-PhoneGap-Plugin.git |
O plug-in Couchbase Lite para o Apache Cordova funciona inteiramente com base nas APIs RESTful disponíveis. Pessoalmente, prefiro não trabalhar com APIs em meu aplicativo, por isso criei um bom wrapper JavaScript para transformar as APIs em uma classe agradável. O wrapper,cordova-couchbasepermitirá que você use métodos em vez de se preocupar com solicitações HTTP para pontos de extremidade.
Para instalar o cordova-couchbase em seu projeto, execute o seguinte:
1 |
npm instalar cordova-couchbase --salvar |
Neste ponto, estamos prontos para começar a desenvolver o aplicativo Ionic 2.
Gerenciando o Couchbase por meio de um provedor Angular 2
Ao trabalhar com bancos de dados em um aplicativo Angular 2, é uma boa ideia mantê-los em um serviço, também conhecido como provedor. Isso nos permite não apenas inicializar grande parte da lógica do banco de dados em um único arquivo, mas também manter nossa camada de banco de dados separada do restante do nosso código.
Usando a CLI do Ionic, execute o seguinte para gerar uma classe de provedor:
1 |
iônico g provedor Provedor do Couchbase |
Essencialmente, o comando apenas cria um diretório e um arquivo em src/providers/couchbase-provider.ts dentro do projeto. Esse provedor deve se parecer com o seguinte:
1 2 3 4 5 6 7 8 9 10 11 |
importação { Injetável } de '@angular/core'; importação { Http } de '@angular/http'; importação { Plataforma } de "iônico-angular; importação { Couchbase, Banco de dados } de 'cordova-couchbase/core'; importação 'rxjs/add/operator/map'; @Injetável() exportação classe Provedor do Couchbase { público construtor(público http:Http) { } } |
Vamos começar a pensar em como nosso serviço do Couchbase funcionará e nas partes do código que serão incorporadas a ele para que seja um sucesso.
Queremos que o nosso serviço de banco de dados funcione como um singleton, ou seja, queremos que uma única classe de banco de dados seja instanciada para todo o aplicativo. Como se fosse um serviço compartilhado. Podemos configurar isso por meio da função construtor
do nosso provedor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
privado isInstantiated:booleano; privado banco de dados:Banco de dados; público construtor(público http:Http, plataforma:Plataforma) { se(!este.isInstantiated) { plataforma.pronto().então(() => { (novo Couchbase()).openDatabase("nraboy").então(banco de dados => { este.banco de dados = banco de dados; este.isInstantiated = verdadeiro; }, erro => { console.erro(erro); }); }); } } |
Então, o que está acontecendo no código acima até agora? Primeiro, criamos duas variáveis privadas. O booleano nos informará se o banco de dados já foi instanciado. A variável Banco de dados
manterá o banco de dados aberto no momento.
Dentro do construtor
estamos fazendo a verificação da lógica condicional. Como o plug-in do Apache Cordova usa código nativo, precisamos ter certeza de que o dispositivo está pronto. Isso é demonstrado por meio do uso do método plataforma.ready
método. Quando o dispositivo estiver pronto, poderemos abrir um banco de dados, mesmo que ele não exista, e defini-lo em nossa variável privada.
1 2 3 |
público getDatabase() { retorno este.banco de dados; } |
O banco de dados aberto pode ser recuperado de nosso provedor usando o getDatabase
método.
Ainda não terminamos com o Provedor do Couchbase
ainda. Provavelmente, devemos pensar em criar nossas exibições de MapReduce para consultas futuras e configurar nosso ouvinte de alterações. Tudo isso ocorrerá na classe construtor
depois de definir o banco de dados aberto.
Por exemplo, agora vamos considerar o seguinte:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
privado isInstantiated:booleano; privado banco de dados:Banco de dados; privado ouvinte:Emissor de eventos = novo Emissor de eventos(); público construtor(público http:Http, plataforma:Plataforma) { se(!este.isInstantiated) { plataforma.pronto().então(() => { (novo Couchbase()).openDatabase("nraboy").então(banco de dados => { este.banco de dados = banco de dados; deixar visualizações = { itens: { mapa:função(doc) { se (doc.tipo == "lista" && doc.título) { emitir(doc._id,{ título: doc.título, rev: doc._rev }) } }.toString() } }; este.banco de dados.createDesignDocument("_design/todo", visualizações); este.banco de dados.ouvir(mudança => { este.ouvinte.emitir(mudança.detalhes); }); este.isInstantiated = verdadeiro; },erro => { console.erro(erro); }); }); } } |
No código acima, adicionamos um ouvinte
que emitirá alterações que podem ser assinadas em nosso código do Angular 2. Dentro da variável construtor
criamos uma visualização MapReduce chamada itens
com lógica que emitirá pares de valores-chave somente se o documento contiver uma propriedade chamada tipo
que é igual a "list" e uma propriedade chamada título
que pode ser igual a qualquer coisa.
A visualização é então adicionada a um documento de design de nossa escolha e o ouvinte é ativado. Com o ouvinte ativado, qualquer alteração no banco de dados o acionará. Isso significa que se adicionarmos um documento, alterarmos um documento ou excluirmos um documento, o ouvinte emitirá a alteração.
1 2 3 |
público getChangeListener(): Emissor de eventos { retorno este.ouvinte; } |
O ouvinte pode ser acessado de várias páginas do aplicativo chamando a função getChangeListener
função.
O provedor foi criado, mas não está sendo compartilhado no aplicativo no momento. Para fazer isso, precisamos importá-lo para o Angular 2 @NgModule
encontrado no bloco src/app/app.module.ts arquivo. Quando concluído, esse arquivo terá a aparência a seguir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
importação { NgModule, Manipulador de erros } de '@angular/core'; importação { IonicApp, IonicModule, IonicErrorHandler } de "iônico-angular; importação { Meu aplicativo } de './app.component'; importação { Página inicial } de '../pages/home/home'; importação { Provedor do Couchbase } de "../providers/couchbase-provider"; @NgModule({ declarações: [ Meu aplicativo, Página inicial ], importações: [ IonicModule.forRoot(Meu aplicativo) ], bootstrap: [IonicApp], entryComponents: [ Meu aplicativo, Página inicial ], provedores: [{fornecer: Manipulador de erros, useClass: IonicErrorHandler}, Provedor do Couchbase] }) exportação classe AppModule {} |
Observe que o provedor foi importado e adicionado ao provedores
array? Agora podemos nos concentrar em adicionar a lógica do aplicativo.
Uso do Couchbase no aplicativo Ionic 2
Provavelmente, é uma boa ideia abrir nosso banco de dados quando o aplicativo for iniciado. Embora possamos fazer isso quando a primeira página for carregada, não é necessário.
Abra o arquivo src/app/app.component.ts e inclua o seguinte código TypeScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
importação { Componente } de '@angular/core'; importação { Plataforma } de "iônico-angular; importação { Barra de status, Tela de respingo } de 'ionic-native' (nativo iônico); importação { Página inicial } de '../pages/home/home'; importação { Provedor do Couchbase } de "../providers/couchbase-provider"; @Componente({ templateUrl: 'app.html' }) exportação classe Meu aplicativo { rootPage = Página inicial; construtor(plataforma: Plataforma, couchbase: Provedor do Couchbase) { plataforma.pronto().então(() => { Barra de status.styleDefault(); Tela de respingo.esconder(); }); } } |
No código acima, importamos o provedor e o injetamos no construtor
método. Isso será acionado antes que a primeira página seja carregada, abrindo o banco de dados, criando a exibição e iniciando o ouvinte.
Daqui em diante, passaremos nosso tempo na primeira e única página do aplicativo. Isso significa que passaremos nosso tempo na página src/pages/home/home.ts e src/pages/home/home.html arquivos.
Abra o arquivo src/pages/home/home.ts e inclua o seguinte código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
importação { Componente, NgZone } de '@angular/core'; importação { NavController, AlertController } de "iônico-angular; importação { Provedor do Couchbase } de "../../providers/couchbase-provider"; @Componente({ seletor: 'page-home', templateUrl: 'home.html' }) exportação classe Página inicial { público itens: Matriz; público construtor(público navCtrl: NavController, público alertCtrl: AlertController, público couchbase: Provedor do Couchbase, público zona: NgZone) { este.itens = []; } público ionViewDidEnter() { } público atualizar() { } público adicionar() { } } |
Vamos detalhar o que isso significa e adicionar cada um dos métodos, um por um.
Você pode ver que estamos importando o Provedor do Couchbase
juntamente com outros componentes. Exploraremos o que cada um deles significa quando chegarmos lá.
O itens
que é público, manterá todos os nossos itens que serão apresentados na interface do usuário, por isso é público. A matriz construtor
tem muitas injeções para cada um dos componentes que planejamos usar. É também onde inicializamos nossa matriz pública.
Nunca é aconselhável carregar dados no construtor
e é por isso que temos o método ionViewDidEnter
método. É nesse método que ocorre a maior parte do trabalho pesado:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
público ionViewDidEnter() { setTimeout(() => { este.couchbase.getChangeListener().assinar(dados => { para(deixar i = 0; i < dados.comprimento; i++) { se(!dados[i].hasOwnProperty("excluído") && dados[i].id.indexOf("_design") === -1) { este.couchbase.getDatabase().getDocument(dados[i].id).então(resultado => { se(resultado.tipo === "lista") { este.zona.executar(() => { este.itens.empurrar(resultado); }); } }); } } }); este.atualizar(); }, 100); } |
Primeiro, você notará o tempo limite. Estamos trabalhando com muitos componentes assíncronos, especificamente o componente Couchbase. Muitas vezes, há uma condição de corrida em que o banco de dados não estará pronto a tempo de ser usado. Adicionar um simples timeout de 100 ms é mais do que suficiente para fazer a bola rolar. Há outras maneiras de fazer isso, mas prefiro o timeout.
Quando a página for carregada, queremos nos inscrever em nosso ouvinte que foi criado no provedor. Faremos um loop de todos os dados emitidos. Neste exemplo específico, estamos ignorando as exclusões e tratando as alterações e adições da mesma forma. Em seu aplicativo, talvez você queira adicionar uma lógica mais específica. Basicamente, estou dizendo que, desde que a alteração não tenha sido uma exclusão, pegaremos a chave que foi alterada e faremos uma pesquisa no documento. Se o documento for um de nossos documentos de tarefas, queremos adicioná-lo à matriz pública.
Então, o que está acontecendo com o zona
coisas? Os emissores podem ficar estranhos, portanto, quando recebemos um evento, queremos atualizar a zona do Angular 2. Você pode achar que isso não é necessário, mas se a interface do usuário não for atualizada com as alterações, não ter o zona
é por isso.
Depois que o ouvinte de alterações tiver sido criado, queremos consultar o banco de dados como ele se encontra no momento. É aqui que o atualizar
entra em ação:
1 2 3 4 5 6 7 8 |
público atualizar() { este.couchbase.getDatabase().visualização de consulta("_design/todo", "itens", {}).então(resultado => { este.itens = []; para(var i = 0; i < resultado.linhas.comprimento; i++) { este.itens.empurrar(resultado.linhas[i].valor); } }, erro => { console.erro("ERRO: " + JSON.stringify(erro)); }); } |
O atualizar
consultará nossa exibição e adicionará cada um dos itens resultantes à nossa matriz pública. Só precisamos consultar uma vez, porque as alterações que chegarem serão automaticamente adicionadas para nós, por conveniência.
O adicionar
é o método final desta página do Ionic 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
público adicionar() { deixar imediato = este.alertCtrl.criar({ título: 'Todo Items', mensagem: "Adicionar um novo item à lista de tarefas", insumos: [ { nome: 'título', espaço reservado: "Título }, ], botões: [ { texto: 'Cancelar', manipulador: dados => {} }, { texto: 'Salvar', manipulador: dados => { este.couchbase.getDatabase().createDocument({tipo: "lista", título: dados.título}); } } ] }); imediato.presente(); } |
Quando executado, um prompt será exibido. Quando o usuário inserir informações no prompt, elas serão salvas como um documento no Couchbase. O ouvinte de alterações pegará essa alteração local e a adicionará à lista.
A interface de usuário simples por trás desse aplicativo, encontrada na seção src/pages/home/home.html tem a seguinte aparência:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<íon-cabeçalho> <íon-barra de navegação> <íon-título> Couchbase w/ Iônico 2 </íon-título> <íon-botões final> <botão íon-botão ícone-somente (clique)="add()"> <íon-ícone nome="adicionar"></íon-ícone> </botão> </íon-botões> </íon-barra de navegação> </íon-cabeçalho> <íon-conteúdo acolchoamento> <íon-lista> <íon-item *ngFor="let item of items"> {{ item.título }} </íon-item> </íon-lista> </íon-conteúdo> |
A interface do usuário tem uma barra de ação com um botão para exibir o prompt. O conteúdo principal é uma exibição de lista em que percorremos a matriz pública do arquivo TypeScript.
Sincronização entre dispositivos e plataformas
Até agora, tudo era local em um único dispositivo. Nada do que adicionamos até agora foi responsável pela sincronização com o Couchbase Sync Gateway ou com outros dispositivos. No entanto, adicionar suporte à sincronização não requer quase nenhum esforço.
Abra o arquivo src/providers/couchbase-provider.ts e inclua a seguinte linha após abrir o banco de dados:
1 |
este.banco de dados.sincronização("http://192.168.57.1:4984/example", verdadeiro); |
Obviamente, troque o nome do host e o nome do banco de dados pelo nome da instância remota do Sync Gateway. Agora seu aplicativo será sincronizado continuamente. Não é incrível que uma linha de código tenha nos dado suporte à sincronização?
Se você deseja ativar uma instância simples do Sync Gateway, aqui e agora, crie o seguinte sync-gateway-config.json file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
{ "log":["CRUD+", "REST+", "Mudanças+", "Anexar+"], "bancos de dados": { "exemplo": { "servidor":"walrus:", "sync":` função (doc) { canal (doc.canais); } `, "usuários": { "CONVIDADO": { "desativado": falso, "admin_channels": ["*"] } } } } } |
Quando você iniciar o Sync Gateway, aponte-o para esse arquivo de configuração específico. Atualize seu sincronização
no aplicativo Ionic 2 para corresponder ao host e ao banco de dados.
Testando o projeto finalizado
Entendo que este guia tenha sido um pouco longo. Eu fui em frente e publiquei um projeto de amostra no GitHub que você pode executar e revisar para complementar este tutorial.
Clone o projeto executando-o:
1 |
git clone https://github.com/couchbaselabs/todolite-ionic2 |
Com o download do projeto, precisamos restaurar as dependências, os plug-ins e as plataformas do projeto. Execute o seguinte para restaurar essas dependências:
1 2 |
npm instalar iônico estado restaurar |
Agora você pode continuar a executar o aplicativo em seu dispositivo ou simulador. Só não se esqueça de executar o Couchbase Sync Gateway e atualizar o arquivo sincronização
para refletir o método de sua configuração remota.
Conclusão
Você acabou de ver como criar um aplicativo móvel híbrido de plataforma cruzada para iOS e Android com o Iônico 2 que usa o Couchbase Mobile. Esse é um passo à frente e uma revisão do meu Artigo anterior que demonstrou o Ionic Framework 1.0 e o Couchbase Mobile.
Olá, equipe,
Estou tentando executar o aplicativo e estou recebendo um alerta na tela inicial como "Couchbase Lite não está instalado"
Mesmo que eu tenha instalado os plug-ins abaixo.
plugin cordova add cordova-plugin-whitelist
adicionar plug-in do cordova https://github.com/couchbaselabs/Couchbase-Lite-PhoneGap-Plugin.git
Você está tentando usar o live-reload, o ionic serve ou o ionic view? Os plug-ins nativos não podem ser emulados dessa forma, eles precisam ser instalados no dispositivo real ou no simulador a partir do binário.
Pode confirmar que não está fazendo uma dessas três coisas?
Obrigado por sua resposta rápida.
Quando executo o comando "ionic cordova run android", recebo a mensagem abaixo durante a compilação. Também estou fornecendo o link da captura de tela
https://firebasestorage.googleapis.com/v0/b/tw-chatapp.appspot.com/o/Capture.PNG?alt=media&token=c3bfa5d6-8246-4196-9a89-7ef6941502a4
[13:03:02] tslint: E:/E WORKS/CouchBase/src/pages/home/home.ts, linha: 4
Importação não utilizada: 'Couchbase'
L3: import { CouchbaseProvider } de "../../providers/couchbase/couchbase";
L4: importar { Couchbase, Database } de "cordova-couchbase/core";
[13:03:02] tslint: E:/E WORKS/CouchBase/src/pages/home/home.ts, linha: 4
Importação não utilizada: 'Database'
L3: import { CouchbaseProvider } de "../../providers/couchbase/couchbase";
L4: importar { Couchbase, Database } de "cordova-couchbase/core";
Depois de iniciar o aplicativo, recebi o erro abaixo.
https://firebasestorage.googleapis.com/v0/b/tw-chatapp.appspot.com/o/mobile.PNG?alt=media&token=e24e91f7-dce9-4c0c-a258-844001d72f0c
Aguardamos sua resposta.
Obrigado.
Olá,
Estou tentando seguir este exemplo, mas não consigo instalar o plug-in Couchbase-Lite-PhoneGap.
Quando tento adicioná-lo usando
"Adicionar plug-in do Ionic Cordova https://github.com/couchbaselabs/Couchbase-Lite-PhoneGap-Plugin.git”
Recebo um erro informando que há um problema de conexão ou que a especificação do plug-in está incorreta. Não é um problema de conexão, posso adicionar outros plug-ins do github com o mesmo comando.
Quando tento contornar o problema, baixar e descompactar o plug-in manualmente e adicioná-lo como um plug-in local com o caminho para a pasta, recebo um erro informando que não há um package.json válido.
O comando é "ionic plugin add" ou "cordova plugin add". Não existe o comando "ionic cordova plugin add".
Melhor,
Na verdade, o comando ionic plugin foi renomeado para ionic cordova plugin.
"Adicionar plug-in do Ionic Cordova https://github.com/couchbaselabs/Couchbase-Lite-PhoneGap-Plugin.git" é o comando correto para instalar o plug-in, e não sei como corrigir o problema do Marburg.
Finalmente consegui configurá-lo agora.
Mas quando tento usar o ionic serve -l no aplicativo, recebo uma mensagem de que this.couchbase.getDatabase(...) is undefined.
Você não pode usar esse plug-in porque ele é nativo. Ele deve ser compilado e instalado como se você estivesse fazendo isso de verdade.
Com certeza! Obrigado pelo feedback. Isso dificulta o desenvolvimento e o recarregamento ao vivo, mas acho que isso também pode ser feito no modo de emulação.
Fim inesperado da entrada JSON em
Couchbase()).openDatabase("todolite").then(......
[16:54:48] console.log: Ionic Native: evento deviceready disparado após 2325 ms
[16:54:48] erro ao abrir a mensagem ws: {"category": "console", "type": "log", "data"
["DEVICE READY FIRED AFTER",2152, "ms"]}
[16:54:48] console.error: ERRO
[objeto Objeto].
[16:54:48] console.error: ERRO
[objeto Objeto].
Olá Nic Raboy,
Sou iniciante no Couchbase e quero desenvolver um aplicativo móvel híbrido para vários usuários em ionic com sincronização de dados.
Já desenvolvi um aplicativo para Android (nativo) com o MySQL como back-end e quero converter esse banco de dados MySQL com o Couchbase para suporte off-line. Então, o que devo seguir e como converter o banco de dados MySQL em Couchbase.
Desde já, obrigado
captura de tela do erro com todos os detalhes.
Comentei a conexão com o sync_gateway, portanto, é já na configuração do banco de dados local que ocorre o erro json.
https://drive.google.com/file/d/0B0KRHtKNSw4xUXdfMWhEcU16Nms/view?usp=sharing
Ele está dentro do wrapper cordova-couchbase. Adicionei esses arquivos ao projeto agora e os chamo localmente.
Até agora, consegui localizá-lo no método makeRequest do database.ts.
Ok, fui o mais longe que pude.
Puxar o wrapper do cordova-couchbase para dentro do projeto e corrigir o erro #3, como fez Murilo Perrone, corrigiu o erro de análise do json, mas não fez a demonstração funcionar.
Adicionei algumas informações de depuração ao console.log, de modo que o evento deviceready é realmente disparado, após 13 segundos,
O couchbase.openDatabase() chama o database.getDatabase(), que chama o método makeRequest com o método GET e a url http://c3c19c87-dcc1-4b6d-a3db-fc7be65a427f:7adfa00d-0fd7-44ea-95b9-3cbe7f0609dd@localhost:5984/councilapp
Tudo isso parece funcionar bem. Mas parece que não retorna nada, porque, mais adiante, this.couchbase.getDatabase() permanece indefinido,
não é possível ler o queryView de undefined,
não é possível ler getDocument de undefined.
Então, tentei por 3 dias, com o conhecimento limitado que tenho, mas simplesmente não consigo mais fazer funcionar. Provavelmente, este é o ponto em que vou desistir.
17:39:22] console.log: O Angular está sendo executado no modo de desenvolvimento. Chame enableProdMode() para habilitar o modo de produção
modo.
17:39:23] console.log: deviceready não foi acionado após 5 segundos.
17:39:23] console.warn: Ionic Native: deviceready não disparou dentro de 5000ms. Isso pode acontecer quando os plug-ins estão em um
estado inconsistente. Tente remover os plug-ins de plugins/ e reinstalá-los.
17:39:23] console.warn: Nativo: deviceready não disparou dentro de 5000ms. Isso pode acontecer quando os plug-ins estão em um
estado inconsistente. Tente remover os plug-ins de plugins/ e reinstalá-los.
17:39:23] console.log: Ionic Native: evento deviceready disparado após 12030 ms
17:39:23] console.log: DISPOSITIVO PRONTO disparado após 11374 ms
17:39:23] console.log: method: GET, url:
http://c3c19c87-dcc1-4b6d-a3db-fc7be65a427f:7adfa00d-0fd7-44ea-95b9-3cbe7f0609dd@localhost:5984/councilapp
17:39:26] console.error: ERRO [objeto Objeto]
O motivo pelo qual não está funcionando para mim é o wrapper cordova-couchbase.
Na linha 18 do couchbase.ts desse projeto, uma promessa é feita com database.getDatabase().then(result......)
na linha 21, você captura os possíveis erros, mas presume que error.status existe.
No meu caso, o erro em si é nulo, portanto, todo o resto também falha.
Tenho uma versão funcionando.
Agora percebo que o plug-in não funciona bem com -livereload.
O aplicativo funciona quando eu o executo em um emulador sem o livereload.
O plug-in trava na primeira ação executada no plug-in quando eu o executo em um emulador com livereload.
DISPOSITIVO PRONTO PARA SER DISPARADO APÓS 590 ms
O Couchbase Lite não está instalado!
EXCEPTION: Não é possível ler a propriedade 'queryView' de undefined
STACKTRACE ORIGINAL:
TypeError: Não é possível ler a propriedade 'queryView' de undefined
at t.refresh (file:///android_asset/www/build/main.js:10:22154)
em file:///android_asset/www/build/main.js:10:22067
at t.invokeTask (file:///android_asset/www/build/polyfills.js:3:14051)
em Object.onInvokeTask (file:///android_asset/www/build/main.js:3:29640)
at t.invokeTask (file:///android_asset/www/build/polyfills.js:3:13987)
em e.runTask (file:///android_asset/www/build/polyfills.js:3:11411)
em invoke (file:///android_asset/www/build/polyfills.js:3:15164)
Veja esta captura de tela
http://prntscr.com/gy09lz