Sync-ing deleted docs

Hi all,

I just noticed that when a doc is deleted the properties for it are removed. Here’s an example of such a doc:

{
  "_deleted": true,
  "_sync": {
    "rev": "2-3246cfb47fff9089f03e27d0ecc3e1da",
    "flags": 1,
    "sequence": 41556,
    "recent_sequences": [
      41556
    ],
    "history": {
      "revs": [
        "1-9b4192deb5352d0bf088941053d4e3ad",
        "2-3246cfb47fff9089f03e27d0ecc3e1da"
      ],
      "parents": [
        -1,
        0
      ],
      "deleted": [
        1
      ],
      "channels": [
        null,
        null
      ]
    },
    "time_saved": "2017-01-02T18:05:53.439783377Z"
  }
}

Now, in our sync function, we use a field (syncUserId) to determine what is visible to a user.

When this property is removed for a deleted doc, how does the sync_gateway know who has access to the deleted doc? Or is it the case that all users get a copy? (terrifying thought)

here’s the sync function:

{
     "interface": ":4984",
     "adminInterface": ":4985",
     "log": ["CRUD", "REST+", "Access"],
     "databases": {
         "ketodiet": {
             "server": "http://localhost:8091",
             "bucket": "ketodiet",
             "sync": `function(doc, oldDoc) {
                 channel(doc.syncUserId);
             }`
         }
     }
 }

Thanks!

@nkonstas you could always do a “soft” delete and just update the document with a PUT/POST and adding the element is the JSON body of “_deleted”:true

We use the iOS & Android client libs – my understanding is that this is default behaviour.

I wouldn’t want to override or alter it - I’d rather fix this properly. I know deleted docs get synced, my suspicion is that every user may get a copy. It’s late here, but, I will test and confirm tomorrow just to be sure.

I am surprised though – I feel like I’m missing something. Don’t mobile apps delete docs? How to they route them to a channel once deleted? Should I always embed the user/channel id in the doc id and use that in the sync function? What do other people do?

Thank you!

So I can answer my own question. I overlooked this method on CBLModel (on iOS)

/** If you want properties to be saved in the document when it's deleted (in addition to the required "_deleted":true) override this method to return those properties.
    This is called by -deleteDocument:. The default implementation returns {"_deleted":true}. */
- (NSDictionary*) propertiesToSaveForDeletion;

I suppose there is a similar API for Android.

Android doesn’t have a Model class, so there’s no direct equivalent to that.

A document deletion, often called a “tombstone”, is simply a revision containing a "_deleted":true property. It’s allowed to have other properties; they’re simply ignored by CBL and SG.

All the deleteDocument method does is save a new revision containing just that property. If you want other properties in your tombstone, just create it manually as @househippo suggested.

Thanks for that - the android dev I work with has written some code to autogen the Java models so it should be trivial to incorporate that change (we do plan to release that code in the future in case it’s useful to other people)

A quick question: to prevent docs without a syncUserId field from being pushed to the DB I plan to change the sync function to throw for such invalid docs:

{
     "interface": ":4984",
     "adminInterface": ":4985",
     "log": ["CRUD", "REST+", "Access"],
     "databases": {
         "ketodiet": {
             "server": "http://localhost:8091",
             "bucket": "ketodiet",
             "sync": `function(doc, oldDoc) {
                 if (!doc.syncUserId) {
                 	throw({forbidden: "Missing user ID"});
                 }
                 channel(doc.syncUserId);
             }`
         }
     }
 }

When docs are being pushed to the SG, where one or more of them are invalid (missing syncUserId), would that stop the sync altogether or only affect (skip) the invalid docs?

for example, if sequence of docs is being pushed:

[doc A]-[doc B]-[invalid doc C]-[doc D]

would the push replication stop & fail at invalid doc C, or, would it skip doc C (with an error) and carry on pushing doc D etc

Thanks

Hi @nkonstas, documents are processes individually by the sync function, so you will get an exception for doc c, but not for a, b and d

Regards,
Vlad