Pedro Gonzalez
Pedro Gonzalez

Reputation: 21

pouchdb-adapter-cordova-sqlite works locally but is not syncing

I have an issue using cordova-sqlite adapter in PouchDB. It works perfect locally (I can create, update and delete docs) but is not able to sync from/to any remote CouchDB server. I tried both IBM Cloudant and a CouchDB server of my own.

If I use IDB adapter instead it works like a charm, but when I change to SQLite is when it cannot sync properly.

This is how I use it (in my case inside a Vue app):

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import PouchDB from 'pouchdb'
...
Object.defineProperty(Vue.prototype, '$pouch', { value: PouchDB }); //this is to be able to use $pouch in any Vue component later on
...
var PouchAdapterCordovaSqlite = require('pouchdb-adapter-cordova-sqlite');
PouchAdapterCordovaSqlite.use_prefix = true; // use the legacy '_pouch' prefix. I tried both with and without this option
PouchDB.plugin(PouchAdapterCordovaSqlite); 
...        
this.db = new this.$pouch('todos', { adapter: 'cordova-sqlite', location: 'default', androidDatabaseImplementation: 2 });

console.log('PouchDB adapter: ' + this.db.adapter); //it returns 'cordova-sqlite'

let remoteCouch='http://myserveraddress.com:5984/todos'; //todos is the remote database, with CORS enabled and set as public so no user/pass is needed

this.$pouch.sync('todos', remoteCouch, {
        live: true,
        retry: true
      }).on('change', function (info) { console.log('change:' + info}).on('paused', function (err) {//...//}).on --- and so on with 'active', 'denied', 'complete' and 'error'

and later in one Vue component I use this (where this.db refers to the database and this.todos is used to show results on screen:

    mounted() {
        this.list();
        this.db
          .changes({
            since: "now",
            live: true
          })
          .on("change", this.list);
      },
      methods: {
      list: function() {
      let self = this;
      this.db.allDocs({ include_docs: true, descending: true }, function(
        err,
        doc
      ) {
        self.todos = doc.rows;
      });
    }
}

As I mentioned before it works with IndexedDB but not with SQLite adapter (I used both cordova-sqlite-storage and cordova-plugin-sqlite-2 with same results). Everything starts after deviceready event and sqlite is loaded properly (I am able to use window.sqlitePlugin).

And when it comes to Cordova config.xml I ensured to define this:

<plugin name="cordova-plugin-whitelist"/>
<access origin="*"/>
<allow-intent href="http://*/*"/>
<allow-intent href="https://*/*"/>
...
<plugin name="cordova-plugin-sqlite-2" spec="*"/>

Any clue? I really need to use SQLite instead of IDB because my app will store big amount of data, and I also need an offline-first approach, that's why I use PouchDB.

Another test that I tried was to create a SQLite database manually from my app and it also works, so it seems that the problem is related to pouchdb-adapter-cordova-sqlite.

Screenshot with IDB: result with idb

And screenshot with SQLite: result with sqlite

Thanks in advance!

Upvotes: 2

Views: 751

Answers (1)

Pedro Gonzalez
Pedro Gonzalez

Reputation: 21

Solved!

The problem was here:

this.$pouch.sync('todos', remoteCouch, {...

It has to be changed to:

this.db.sync(remoteCouch, {...

So it was pointing to pouchdb object instead of the database instance. I hope it helps someone. Regards!

Upvotes: 0

Related Questions