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

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": [
    "history": {
      "revs": [
      "parents": [
      "channels": [
    "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
            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];

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: