Ember-data offline data persistence, maybe ember-pouch is not useful? Maybe I need something else?

I have a simply application with ember-data that uses DS.JSONAPIAdapter in adapters/application.js because I’m using a backend with JSON API.

import DS from "ember-data";
import DataAdapterMixin from "ember-simple-auth/mixins/data-adapter-mixin";
import ENV from "../config/environment";

export default DS.JSONAPIAdapter.extend(DataAdapterMixin, {
  host: `${ENV.API_HOST}`,

  namespace: "api"
});

Now I need for some models (and in some scenarios) the user can use my application also in offline mode.

So I thought at pouchdb and ember-pouch. But maybe I was wrong.

Let’s say I today write a new post and click the save() button. Now my post is saved through ember-data which is online and says to my server backend to save it through application adapter.

Now my server can save or not this post (maybe it can refuse it because of many words or maybe other validations server-side only).

So after save() my server can say NO! to my client (and to ember-data) or maybe YES!: so I have logical, business operations in my server backend.

With ember-pouch I don’t understand:

  • I really need ember-pouch for this problem?
  • how to backup data in client (when offline) just for some models (let’s say post and category and tags);
  • how to add ember-pouch just to handle offline mode and retry operations when online for that models using my server backend (and also a couchdb one just for ember-pouch);
  • maybe I’m wrong because any application that uses ember-pouch has to do without the server using only couchdb one? So all the logic is just in client (ember) side? Is this one the right way?
  • how to add ember-pouch in an application just for some models using belongsTo relationship with standard ember-data models?

@broerse, maybe can you help me understand better?

Yes I think I can. Will try to find some time tomorrow to reply.

Any news dear @broerse?

If you want to create a progressive web app you need a way to store your relational data when offline. PouchDB can store the data offline and will make the data eventually consistent via the sync to a CouchDB backend like Cloudant. You need ember-pouch as an ember-data adapter but also for the relational data and the eventually consistent behavior.

Let talk a bit about the problems there are with all local database like PouchDB. On a classic SQL backend when you store the belongsTo it also updates the hasMany side. This is not something ember-data does. PouchDB is just a document store so by default if you store the belongsTo noting happens on the hasMany side. At first you think “This is easy, just update the hasMany side when you change the belongsTo” but there is a problem with this in an offline eventually consistent database. An other user can get the hasMany data first without receiving the belongsTo yet. ember-pouch solves this with the ENV.emberpouch.dontsavehasmany flag. This flag enables backend like behavior on the frontend by creating the hasMany for ember-data. So it is available in the ember-data models but not on the CouchDB backend. An other problem is that ember-data does not wait for ID’s that will sync in later. So from ember-pouch v5.0.0-beta.1 we added eventually consistent support.

I will try to answer your question list.

  • ember-pouch is at the moment the only eventually consistent offline relational database for ember-data I know off. So I think you need it in off-line Apps.
  • You can make an adapter per model. The backup works out-off-the-box.
  • The how to add ember-pouch just to handle offline question I don’t understand. Perhaps the question is if ember-pouch will start syncing data when back on-line. It does out-off-the-box.
  • All the logic has to be in Ember to work off-line in a progressive web app. There is little to none logic on the server required.
  • Mixing pouch models with on-line models can easily be done by creating adapters for the Pouch models or the other way around. Perhaps creating adapters for the on-line models is better because the application will work off-line until you enter a route that needs the on-line models. The ‘belongsTo’ will not work with the dontsavehasmany flag leaving you in charge off saving the hasMany side. So I think this mix could be very error sensitive. Perhaps more robust is to sync your on-line data with CouchDB and let ember-pouch handle all models.

If you let your backend sync the data with CouchDB you will only need one authentication layer. There is no documentation yet but we have a working addon for Simple Auth GitHub - martinic/ember-simple-auth-pouch: Authenticator for ember-simple-auth using pouchdb-authentication

I hope this helps you decide what to do.