I have been playing around with the sync. function to try and get it to reflect the sync that I need (and not least for me to try to understand how it processes the documents both for reads - channels - and for writes - require…).
So I’m getting closer to getting it right . However, I see some minor differences in the documents on the server and in mobile. I’ve been able to track down an example - and to my best understanding the missing document should also replicate to mobile… So first the document (#159) that does not sync - and another of same type (#159) that does:
FishingClub:159
{
"sendmailtoreporter": false,
"enableboastcatches": false,
"enablerecordcatches": false,
"enablememberpubliccatches": false,
"unid": "89A61C8808A7BE13C1257C2000780996",
"catchesincludephotos": false,
"catchesshowchart": false,
"catchesincludenames": false,
"enablestatistics": false,
"revisioninfo": {
"modifiedcount": 0,
"createdby": "John Dalsgaard/D-D",
"created": "2013-11-11T22:50:38+0100"
},
"type": "FishingClub",
"externalreporting": false,
"inactive": false,
"onlyclubmembers": false,
"catchesincludebait": false,
"ispublic": true,
"name": "Vemb Lystfiskerforening",
"catchesincludecomments": false,
"enablegooglechart": false,
"enablelatestcatches": false,
"sendmailtoadmin": false,
"key": "159",
"mandatoryreporting": false
}
And it’s meta data:
{
"meta": {
"id": "FishingClub:159",
"rev": "1-158fc994b23500000000000002000000",
"expiration": 0,
"flags": 33554432,
"type": "json"
},
"xattrs": {}
}
And this one that does sync:
FishingClub:158
{
"_id": "FishingClub:158",
"_rev": "1-686e32eb34507db4cb27cfbf1bc669d2",
"sendmailtoreporter": false,
"enableboastcatches": false,
"enablerecordcatches": false,
"enablememberpubliccatches": false,
"unid": "99BC661C72404CA4C1257C2000780995",
"catchesincludephotos": false,
"catchesshowchart": false,
"catchesincludenames": false,
"enablestatistics": false,
"revisioninfo": {
"created": "2013-11-11T22:50:38+0100",
"createdby": "John Dalsgaard/D-D",
"modifiedcount": 0
},
"type": "FishingClub",
"externalreporting": false,
"inactive": false,
"onlyclubmembers": false,
"catchesincludebait": false,
"ispublic": true,
"name": "Vejle Sportsfiskerforening",
"catchesincludecomments": false,
"enablegooglechart": false,
"enablelatestcatches": false,
"sendmailtoadmin": false,
"key": "158",
"mandatoryreporting": false
}
And it’s meta data:
{
"meta": {
"id": "FishingClub:158",
"rev": "6-15cd3f528c9900000000000002000000",
"expiration": 0,
"flags": 33554432,
"type": "json"
},
"xattrs": {
"_sync": {
"rev": "1-686e32eb34507db4cb27cfbf1bc669d2",
"sequence": 122704,
"recent_sequences": [
122704
],
"history": {
"revs": [
"1-686e32eb34507db4cb27cfbf1bc669d2"
],
"parents": [
-1
],
"channels": [
[
"!"
]
]
},
"channels": {
"!": null
},
"cas": "0x0000998c523fcd15",
"value_crc32c": "0x17fc2714",
"time_saved": "2019-10-11T00:46:46.841427353+02:00"
}
}
}
They are both public documents ("ispublic": true
) and that should make them both replicate (according to the sync. function below).
I have tried to take the database offline and do a resync - it makes no difference.
I have searched the log files:
grep "FishingClub:158" sg_info.log
2019-10-13T18:37:19.643+02:00 [INF] Javascript: Sync SG: doc id: FishingClub:158, ispublic: true, userkey=undefined, creation
2019-10-13T18:37:19.643+02:00 [INF] Javascript: Sync SG: public, id: FishingClub:158
grep "FishingClub:159" sg_info.log
grep "FishingClub:158" sg_warn.log
grep "FishingClub:159" sg_warn.log
grep "FishingClub:158" sg_error.log
grep "FishingClub:159" sg_error.log
As you can see there is only mentioning of the one that replicates Ok - no mentioning of the other in any of the logs…
Finally, here is my sync. function:
function (doc, oldDoc) {
function _log(t) {
// Write to sg_info.log
console.log('SG: ' + t);
}
function _getUserKey(d) {
var key = null;
if (d) {
if (d.type == 'User') {
key = d.key;
} else {
key = d.userkey;
}
}
return key;
}
if (doc && doc._deleted) {
// Doc. deleted -> if public then require
if(oldDoc){
var userkey = _getUserKey(oldDoc);
_log('delete doc id: ' + doc._id + ', userkey=' + userkey);
if (userkey != null) {
requireUser(userkey);
} else {
requireAdmin();
}
}
_log('doc deleted, id: ' + (doc._id || 'no id!') + ', ' + (oldDoc ? ('old key=' + oldDoc.key + ', userkey=' + userkey) : 'no oldDoc'));
return;
}
_log('doc id: ' + (doc._id || 'no id!') + ', ispublic: ' + doc.ispublic + ', userkey=' + userkey + ', ' + (oldDoc ? (oldDoc._deleted ? 'oldDoc is deleted' : ('old key=' + oldDoc.key + ', oldDoc.userkey=' + oldDoc.userkey + ' update')) : ' creation'));
// Document type is mandatory
if (typeof doc.type === 'undefined') {
_log('Document type missing: ' + JSON.stringify(doc));
throw ({ forbidden: "Document type is required. id=" + doc._id });
}
// Document key is mandatory
if (typeof doc.key === 'undefined') {
_log('Document key missing: ' + JSON.stringify(doc));
throw ({ forbidden: "Document key is required. id=" + doc._id });
}
// Update: Cannot allow change of type or key
if (oldDoc != null && !oldDoc._deleted) {
// Update
if (oldDoc.type != doc.type) {
throw ({ forbidden: "Can't change doc type" });
}
if (oldDoc.key != doc.key) {
throw ({ forbidden: "Can't change doc key" });
}
}
// Document sync is disabled (used for type Image)
if (doc.issyncdisabled) {
throw ({ forbidden: "Sync. disabled for id=" + doc._id });
}
// All public docs are available in the app
if (doc.ispublic) {
_log('public, id: ' + (doc._id || 'no id!'));
channel('!');
}
// All non-club/-assoc fishing trips and catches are available (for stats)
if ((doc.type == 'FishingTrip' || doc.type == 'Catch') && doc.userkey) {
_log('non-club/-assoc trip/catch, id: ' + (doc._id || 'no id!'));
channel('!');
}
// All users are available (for stats)
if (doc.type == 'User') {
_log('User doc, id: ' + (doc._id || 'no id!'));
channel('!');
}
// Allow anyone to create a Feedback or Observation on the server
if (oldDoc == null && doc.userkey == null && (doc.type == 'Feedback' || doc.type == 'Observation')) {
_log('Created ' + doc.type + ': ' + (doc._id || 'no id!') + ', key: ' + doc.key + ' as anonymous user ');
return;
}
// Only non-public docs "owned" by user can be created/updated (and replicated)
var userkey = _getUserKey(doc);
if (userkey != null) {
if (oldDoc != null && ! oldDoc._deleted) {
// Update
if (oldDoc.userkey && oldDoc.userkey != doc.userkey) {
throw ({ forbidden: "Can't change user key" });
}
}
_log('User owned, id: ' + (doc._id || 'no id!') + ', type: ' + doc.type + ', user: ' + userkey);
channel('channel.' + userkey);
access(userkey, 'channel.' + userkey);
requireUser(userkey);
} else if (doc.ispublic) {
requireAdmin();
} else {
// Creation/update without user
_log('Document type cannot be created without user key: ' + (doc.type === 'Image' ? doc._id : JSON.stringify(doc)));
throw ({ forbidden: "This document type cannot be created without user key. id=" + doc._id });
}
}
And for completeness I have also included the import filter - just to show that it shouldn’t have any impact of this issue:
function(doc) {
// Some document types not allowed on mobile
if (doc.type == 'EnvLake' || doc.type == 'EnvMeasurement' || doc.type == 'ActivityLog' || doc.type == 'Feedback' || doc.type == 'Image') {
return false;
}
if ((doc.type == 'FishingTrip' || doc.type == 'Catch') && typeof doc.clubonlykey !== 'undefined' && doc.clubonlykey != '') {
return false;
}
return true;
}
How can I debug this issue? Is there any way a can “clean” the history and get the sync. gateway to resync ? What could be the reason that “FishingClub:159” does not replicate???