3

Is it possible to manage the sync conflicts from the client?

What I mean is, when pouchDB does a sync and detects a conflict, is it possible to get the local doc PouchDB is trying to sync and the last revision of CouchDB doc? If I can get both docs, I can display them to the user and he can choose which version to keep...

Nate
  • 7,606
  • 23
  • 72
  • 124

1 Answers1

8

You're in luck, because this is exactly the problem CouchDB and PouchDB were designed to solve.

Basically you can read up on the CouchDB docs on conflict resolution. Everything in there should also apply to PouchDB. (If it doesn't, it's a bug. ;)). The CouchDB wiki also has a nice writeup.

Edit: so to provide more details, you'll want to fetch the document with ?conflicts=true ({conflicts:true} in PouchDB). E.g. you'll fetch a doc like this:

http://localhost:5984/db1/foo?conflicts=true

And get a doc back like this:

{
  "_id":"foo",
  "_rev":"2-f3d4c66dcd7596419c76b2498b3ba21f",
  "notgonnawork":"this is from the second db",
  "_conflicts":["2-c1592ce7b31cc26e91d2f2029c57e621"]
}

Here I have a conflict introduced from another database, and that database's revision has won (randomly). This document's current revision starts with 2-, and the conflicting version also starts with 2-, indicating that they're both at the same level of the revision tree.

To get the conflicting version, you just grab the conflicting rev and call:

http://localhost:5984/db1/foo?rev=2-c1592ce7b31cc26e91d2f2029c57e621

And you get:

{
  "_id":"foo",
  "_rev":"2-c1592ce7b31cc26e91d2f2029c57e621",
  "notgonnawork":"this is from the first database"
}

So after presenting the two conflicting versions to the user, you can then add a 3rd revision on top of both of these, which either combines the results, or chooses the losing version, or whatever you want. This next revision will be prefixed with 3-. Make sense?

Edit: Apparently you also need to delete the conflicting version, or else it will still show up in _conflicts. See this answer.

Community
  • 1
  • 1
nlawson
  • 11,510
  • 4
  • 40
  • 50
  • I think I didn't express my question correctly... The question is more how do you do it. I have a couchdb server with multiple pouchdb clients so when one of my client has a conflict with the server, I get a 409 error (conflict avoidance chapter from couchdb wiki). As PouchDB does the sync transparently, how can I get the conflicting doc (of the server and of the client). In the db.change callback, I only get the error: {status: 409, name: "conflict", message: "Document update conflict", error: true, toString: function}... how to get the docs? – Nate Jun 13 '14 at 13:46
  • When you `get` a document, use `conflicts=true` ([link](https://wiki.apache.org/couchdb/HTTP_Document_API#Special_Fields)). I've edited my answer with some more details. – nlawson Jun 13 '14 at 15:51
  • Sorry, I missed the conflicts argument from PouchDB's API! Thanks! BTW, is the first item in the _conflicts array the last conflict recorded? – Nate Jun 16 '14 at 19:38
  • I'm not sure, but you can always determine the order of conflicts because the `rev`s should be named like '`1-'`, `'2-'`, `'3-'`, etc. – nlawson Jun 18 '14 at 18:11