1

Is there a way I can dynamically change sync function for eg. Lets ssy my documents have a field ID and I want to get documents belonging to a particular ID so ID is my variable here. eg. below is a sync function for ID=4

"sync":
    function (doc) {
        if(doc.ID==4){
            channel (doc.channels);
        }
        else{
            throw({forbidden: "Missing required properties"});
        }
    }, 

Now This will only work for ID=4. How Can I make my sync function dynamic. Is there a way I can supply arguments to my sync function?

EDIT 1 Added Use Case

Ok so my use case is like this.I have an app in which when a user logs in I need to get user specific data from CouchBase Server to CouchBase lite. In My CouchBase Server I have 20000 documents and for each user there are 5 documents so I have (20000/5) 4000 users. So When a user logs in to my app my CouchBase server should send only 5 documents which are related to that user and not all 20000 documents

EDIT 2

This is how I have implemented the replication

private URL createSyncURL(boolean isEncrypted){
    URL syncURL = null;
    String host = "http://172.16.25.108";
    String port = "4986";
    String dbName = "sync_gateway";
    try {
        //syncURL = new URL("http://127.0.0.1   :4986/sync_gateway");
        syncURL = new URL(host + ":" + port + "/" + dbName);
    } catch (Exception me) {
        me.printStackTrace();
    }
    Log.d(syncURL.toString(),"URL");
    return syncURL;
    }
    private void startReplications() throws CouchbaseLiteException {
    Log.d(TAG, "");
    Replication pull = database.createPullReplication(this.createSyncURL(false));
    Replication push = database.createPushReplication(this.createSyncURL(false));
    Authenticator authenticator = AuthenticatorFactory.createBasicAuthenticator("an", "1234");
    pull.setAuthenticator(authenticator);
    //push.setAuthenticator(authenticator);
    List<String> channels1 = new ArrayList<String>();
    channels1.add("u1");
    pull.setChannels(channels1);
    pull.setContinuous(true);
       // push.setContinuous(true);
    pull.start();
    //push.start();
    if(!push.isRunning()){
        Log.d(TAG, "MyBad");
    }
    /*if(!push.isRunning()) {
        Log.d(TAG, "Replication is not running due to " +push.getLastError().getMessage());
        Log.d(TAG, "Replication is not running due to " +push.getLastError().getCause());
        Log.d(TAG, "Replication is not running due to " +push.getLastError().getStackTrace());
        Log.d(TAG, "Replication is not running due to " +push.getLastError().toString());
    }*/
    }
Legendary_Hunter
  • 1,040
  • 2
  • 10
  • 29
  • What do you want to achieve by those parameters? Your sync function will be applied to each inserted, changed, or deleted document. It will run by itself, so you can't call it from outside to provide it with some new argument values. It will have the entire document to process available, but nothing else. So when and where from should the arguments come? – TAM May 05 '16 at 20:05
  • 1
    I have added more explanation. Please revert back if you didnt understand I will add examples for more clarity – Legendary_Hunter May 05 '16 at 20:54

1 Answers1

1

The easiest way to achieve this is to qualify each user to one channel, named like the user, and to give to a document the channel (= user) names of all users for whom this document is relevant (maybe just one channel name per document, but that's completely up to you).

So with the standard sync function (without any if condition), if your config.json contains

        "users": {
            "u1": {
                "admin_channels": ["u1"],
                "password": "abracadabra"
            },
            "u2": {
                "admin_channels": ["u2"],
                "password": "simsalabim"
        ...

and you have documents having

{"channels": "u1",...

{"channels": "u2",...

{"channels": ["u1", "u2"],...

then the first will be transferred to u1, the second to u2, and the third to both of them. You don't need to make your channel names identical to the user name, but for this scenario it's the easiest way to go.

The programmatic assignment of channels to users can be done via the Sync Gateway Admin REST API, see http://developer.couchbase.com/documentation/mobile/1.2/develop/references/sync-gateway/admin-rest-api/user-admin/post-user/index.html. (Note that the Admin API should run on a port that is opened only to the local server where CB runs, not to the public.)

TAM
  • 1,731
  • 13
  • 18
  • Bu the problem is currently I have like 4000 users so do I have to make 4000 channels manually? and more users would be registering so whenever a user registers I have to make channel of that user manually? Isnt there some automated system to make channels? – Legendary_Hunter May 06 '16 at 07:05
  • Extended that answer to cover this too. – TAM May 06 '16 at 16:53
  • Hi, TAM I used the above method and I am able to channelise my documents. But When I use API to create users I am not able to pull my documents(Push is working). I get the following error `PullerInternal{unknown, pull, 93166}: Received invalid doc ID from _changes: {seq=4, id=_user/an, changes=[]}` and on the cosol of syncgateway it is continuously running without stopping I mean I can see infinite POST request for same document and running – Legendary_Hunter May 09 '16 at 07:57
  • Could it be that you inserted or changed documents in a bucket administered by Sync Gateway directly, i.e. not using the Sync Gateway REST API? That way you could have corrupted the SG data structures. – TAM May 09 '16 at 08:19
  • NO I am inserting it using sync gateway only. I am very well aware of the fact that doing directly can corrupt sync gateway. I have also added code which I am using for replication, And the only different in two methods is how I am creating the users. When I create users directly in config file I am good to go but when I use REST API(sync gateway api to create users) I am having pull replications problem – Legendary_Hunter May 09 '16 at 10:51
  • A similar problem is discussed in https://forums.couchbase.com/t/issues-pulling-data-from-sync-gateway-received-invalid-doc-id-from--changes/7750. – TAM May 09 '16 at 11:04
  • My issue is a little different. My issue is when I am hardcoding users in sync gateway config file all is ok, But when I am using REST API to create the users I am unable to pull data – Legendary_Hunter May 09 '16 at 11:33
  • I have now found my problem please refer to the following https://forums.couchbase.com/t/channelising-in-couchbase-sync-gateway-calling-infinitely-post-calls/8165 post and help me out if you can – Legendary_Hunter May 10 '16 at 11:59
  • I guess that kind of problem is well positioned in the CB forum, and the guys there are more competent when it comes to internal error conditions as I am. – TAM May 10 '16 at 14:27