1

I've got android and web apps. Android app uses Couchbase Lite, web app uses Couchbase. I'm using Couchbase Sync Gateway to enable data replication between those two databases.

When user logs in to mobile app for the first time I'd like to pull replicate the document with data on this specific user (based on username). I read that filtered replication is supported by Couchbase Lite (1) but I'm quite confused which method should I use.

What I want to do is a bit similar to this, so I guess my filter function would be like:

function (doc, req) { 
    if(doc.DocType && doc.DocType == "User" && doc.IsActive && doc.Login == req.query.text) 
        { return true } 
    else 
        {return false} 
}

but I've got no idea where should I create this function (in my web app code? I found only DesignDocument.create() but it inserts only View functions).

I read that with SyncGateway I should use channels, but as far I understand channels base on static property of a document and I need to use username as a dynamic parameter.

How can I manage to pull replicate only this specific document?

edit.

So previously my SyncGateway config sync property was like:

"sync":`
            function (doc) {
            channel (doc.channels);
        }`

and it worked normally without filers. I turned it into:

"sync":`
            function (doc, oldDoc) {                 

                if(doc.DocType=="User" && doc.IsActive){
                    channel(doc.Login);
                }
                else {
                    channel (doc.channels);
                }
        }`

and my Java method is:

public void startFirstLoginReplication(String login, String password) throws CouchbaseLiteException{

    (...)
    pull = DatabaseManager.getDatabaseInstance().createPullReplication(this.createSyncURL(false));

    List<String> channels = new ArrayList<String>();
    channels.add(login);
    pull.setChannels(channels);

    pull.setContinuous(false);

    pull.start();

    progressDialog = showLoadingSpinner();

    pull.addChangeListener(this);   
}

With normal replication, when it was updated method changed() was called. With filter it is not, nothing is pulled and progressDialog is stuck.

In SyncGateway console I get:

2016-06-27T23:45:46.081+02:00 HTTP:  #003: GET     /kris_mobile_db/_local/01ef0a1ec2301f9f9f3bb2fae9d352d26fd4a9a7
2016-06-27T23:45:46.094+02:00 HTTP: #003:     --> 404 missing  (14.5 ms)
2016-06-27T23:45:46.300+02:00 HTTP:  #004: POST /kris_mobile_db/_changes
2016-06-27T23:45:46.301+02:00 Changes: MultiChangesFeed({Mo}, {Since:0 Limit:0 Conflicts:true IncludeDocs:false Wait:false Continuous:false  Terminator:0xc08245cba0 HeartbeatMs:300000 TimeoutMs:300000}) ...
2016-06-27T23:45:46.301+02:00 Changes+: MultiChangesFeed: channels expand to channels.TimedSet{"Mo":0x1} ...
2016-06-27T23:45:46.301+02:00 Changes+: MultiChangesFeed sending &{Seq:1 ID:_user/GUEST Deleted:false Removed:{} Doc:map[] Changes:[] Err:<nil> branched:false}
2016-06-27T23:45:46.302+02:00 Changes: MultiChangesFeed done

What am I missing?

Mohru
  • 725
  • 1
  • 7
  • 17

2 Answers2

0

Filtered pull replications with Sync Gateway are based on channels (see the docs). You could create a channel for each username. The Sync Function could map each document to the channel named after the username property:

function (doc, oldDoc) {
  channel(doc.username);
}

You can create a channel for each user on Sync Gateway. There's no limit to how many channels can be created or how many documents one can contain.

PS: Filtered pull replications with a filter function aren't supported in Couchbase Sync Gateway.

jamiltz
  • 1,144
  • 8
  • 15
  • Hi @jamiltz! I updated my question and would appreciate if you could take a look at it. – Mohru Jun 27 '16 at 22:21
0

You should use channels for this use case. For each document give a property named channels and channels should be unique for every user. Now when you pull document you can tell sync gateway from which channel to pull. So basically you can pull from different channels(dynamic pulling).

Remember that when setting channels property it is an array of strings not only one string

Legendary_Hunter
  • 1,040
  • 2
  • 10
  • 29