Channels not being respected on replication

I’m trying to replicate a subset of my data to the device (iOS). I’ve set up my sync function like so:

      "sync" : `function(doc) {
        if (doc.category == "free")    
          channel("free")  // Mark doc for inclusion in initial dataset to be bundled with app
        
        channel(doc.wordlist); 
      }`

and after a resync I can see the channels have been correctly set for the documents I’ve checked, e.g.

  "_sync": {
    "rev": "2-d6c34f36f091eab449281ff11afbcd89",
    "sequence": 7688,
    "recent_sequences": [
      7687,
      7688
    ],
    "history": {
      "revs": [
        "1-afa89c4a424a5ca2dbf2498719ae0571",
        "2-d6c34f36f091eab449281ff11afbcd89"
      ],
      "parents": [
        -1,
        0
      ],
      "channels": [
        null,
        [
          "br",
          "free"
        ]
      ]
    },
    "channels": {
      "br": null,
      "free": null
    },

I’ve also double checked that the replication channel has been set in the CBLite call. But I am getting all the documents!
I don’t understand why - anything else I might have missed? I just want something equivalent to a filtered pull.

After reading this thread, I also added a “filter” parameter of “sync_gateway/bychannel” - is this necessary? It has not made any difference anyway…

What’s the CBLite code you’re using to start the pull replication?

Here you go. Note this is part of a React Native project, inside a RCT_EXPORT_METHOD, hence the resolve and reject calls (they resolve the promise on the JS side), also the RCTConvert is a utility for converting parts of JSON objects to Objective-C equivalent types.

    CBLDatabase* db = [manager existingDatabaseNamed:databaseLocal error:nil];
    if (!db) {
        reject(@"not_opened", [NSString stringWithFormat:@"Database %@: could not be found", databaseLocal], nil);
    } else {
        // Establish the connection.
        NSURL *url = [NSURL URLWithString:remoteUrl];
        CBLReplication* pull = [db createPullReplication: url];

        if (remoteUser && remotePassword) {
            id <CBLAuthenticator> auth = [CBLAuthenticator
                    basicAuthenticatorWithName:remoteUser
                                      password:remotePassword];
            pull.authenticator = auth;
        }

        pull.continuous = [RCTConvert BOOL:options[@"continuous"]];
        pull.channels = [RCTConvert NSStringArray:options[@"channels"]];
        if (pull.channels) NSLog (@"Set replication channels: %@", pull.channels);
        pull.filter = [RCTConvert NSString:options[@"filter"]];
        pull.filterParams = [RCTConvert NSDictionary:options[@"filterParams"]];
        if (pull.filter) NSLog (@"Set filter '%@' with params '%@'", pull.filter, pull.filterParams);
        pull.documentIDs = [RCTConvert NSStringArray:options[@"documentIDs"]];

        if (timeout > 0) {
            pull.customProperties = @{
                                      @"poll": [NSNumber numberWithInteger:timeout],
                                      @"websocket": @false
                                      };
        }
        [pulls  setObject:pull forKey:databaseLocal];
        // Add the events handler.
        if (events) {
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleReplicationEvent:) name:kCBLReplicationChangeNotification object:pull];
        }
        
        [pull start];
    }
    resolve(@{});
 

Hmm… Don’t set the filter or filterParams properties. Those are for use with CouchDB only. I think that setting them will overwrite previous values for channels, but I’m not sure. Likewise, you can’t use both documentIDs and channels; one will override the other.

1 Like

Thanks, that was the issue - I’m now setting them exclusively (well, channels only) and it works as expected :slight_smile: