I am getting started with Couchbase Mobile. The feature that I am most interested (for now) is PULL
replication (keep data on mobile in sync with backend database).
I followed the steps described in Using Docker to develop with Couchbase Mobile and have got the Couchbase server (enterprise-6.5.0) and sync gateway (2.7.0-enterprise) deployed locally. I have added the beer-sample
database (has ~8400 documents) and now I'm trying to replicate it on an android application. I customized the Userprofile Couchbase Mobile Android project and I pointed it to my local sync-gateway. I have a piece of code to replicate like below :
public static void startPullReplication() {
Log.i("Pull", "Start pull beer-sample");
URI url = null;
try {
url = new URI(String.format("%s/%s", "ws://10.0.1.7:4984", beerSampleDbName));
} catch (URISyntaxException e) {
e.printStackTrace();
}
ReplicatorConfiguration config =
new ReplicatorConfiguration(beerSampleDatabase, new URLEndpoint(url)); // <1>
config.setReplicatorType(ReplicatorConfiguration.ReplicatorType.PULL); // <2>
config.setContinuous(true); // <3>
config.setAuthenticator(new BasicAuthenticator("admin", "password")); // <4>
// config.setChannels(Arrays.asList("channel." + "admin")); // <5>
replicator = new Replicator(config);
replicatorListenerToken =
replicator.addChangeListener(
new ReplicatorChangeListener() {
@Override
public void changed(ReplicatorChange change) {
Log.i("Pull", "Changed pull beer sample : " + change.getStatus());
if (change
.getReplicator()
.getStatus()
.getActivityLevel()
.equals(Replicator.ActivityLevel.IDLE)) {
Log.i("Replication Comp Log", "Scheduler Completed");
}
if (change
.getReplicator()
.getStatus()
.getActivityLevel()
.equals(Replicator.ActivityLevel.STOPPED)
|| change
.getReplicator()
.getStatus()
.getActivityLevel()
.equals(Replicator.ActivityLevel.OFFLINE)) {
Log.i("Rep Scheduler Log", "ReplicationTag Stopped");
}
}
});
replicator.start();
Log.i("Pull", "Replication beer-sample started");
}
and listen to changes in the db like below :
private void registerForDatabaseChanges() {
beerSampleListenerToken =
beerSampleDatabase.addChangeListener(
new DatabaseChangeListener() {
Integer i=0;
@Override
public void changed(@NonNull DatabaseChange change) {
Log.i("DatabaseChangeEvent", String.valueOf(i));
i++;
for (String docId : change.getDocumentIDs()) {
Document doc = beerSampleDatabase.getDocument(docId);
if (doc != null) {
Log.i("DatabaseChangeEvent", doc.getId() + ": Document was added/updated");
} else {
Log.i("DatabaseChangeEvent", docId + "Document was deleted");
}
}
}
});
}
Now when I run the app I am getting the following logs.
2020-02-11 15:44:46.420 22513-22513/com.cbmob.testapp W/CouchbaseLite/DATABASE: Database.log.getFile().getConfig() is null, meaning file logging is disabled. Log files required for product support are not being generated.
2020-02-11 15:44:46.615 22513-22545/com.cbmob.testapp D/OpenGLRenderer: HWUI GL Pipeline
2020-02-11 15:44:46.744 22513-22545/com.cbmob.testapp I/zygote: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
2020-02-11 15:44:46.744 22513-22545/com.cbmob.testapp I/OpenGLRenderer: Initialized EGL, version 1.4
2020-02-11 15:44:46.744 22513-22545/com.cbmob.testapp D/OpenGLRenderer: Swap behavior 1
2020-02-11 15:44:46.745 22513-22545/com.cbmob.testapp W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
2020-02-11 15:44:46.745 22513-22545/com.cbmob.testapp D/OpenGLRenderer: Swap behavior 0
2020-02-11 15:44:46.752 22513-22545/com.cbmob.testapp D/EGL_emulation: eglCreateContext: 0xa9f30d40: maj 3 min 0 rcv 3
2020-02-11 15:44:46.765 22513-22545/com.cbmob.testapp D/EGL_emulation: eglMakeCurrent: 0xa9f30d40: ver 3 0 (tinfo 0x9f7bf880)
2020-02-11 15:44:46.976 22513-22545/com.cbmob.testapp D/EGL_emulation: eglMakeCurrent: 0xa9f30d40: ver 3 0 (tinfo 0x9f7bf880)
2020-02-11 15:44:56.458 22513-22513/com.cbmob.testapp I/Pull: Start pull beer-sample
2020-02-11 15:44:56.480 22513-22576/com.cbmob.testapp W/CouchbaseLite/NETWORK: C4Socket.open() socket -> 2852069288
2020-02-11 15:44:56.480 22513-22576/com.cbmob.testapp W/CouchbaseLite/NETWORK: C4Socket.open() clazz -> com.couchbase.lite.internal.replicator.CBLWebSocket
2020-02-11 15:44:56.482 22513-22513/com.cbmob.testapp I/Pull: Replication beer-sample started
2020-02-11 15:44:56.497 22513-22513/com.cbmob.testapp I/Pull: Changed pull beer sample : Status{activityLevel=CONNECTING, progress=Progress{completed=0, total=0}, error=null}
2020-02-11 15:44:56.519 22513-22576/com.cbmob.testapp D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2020-02-11 15:44:56.528 22513-22576/com.cbmob.testapp E/CouchbaseLite/NETWORK: CBLWebSocket.socket_open()
2020-02-11 15:44:56.582 22513-22576/com.cbmob.testapp W/CouchbaseLite/NETWORK: C4Socket.write() handle -> 2852069288
2020-02-11 15:44:56.586 22513-22576/com.cbmob.testapp W/CouchbaseLite/NETWORK: completedWrite(long) handle -> 2852069288, byteCount -> 68
2020-02-11 15:44:56.591 22513-22513/com.cbmob.testapp I/Pull: Changed pull beer sample : Status{activityLevel=BUSY, progress=Progress{completed=0, total=0}, error=null}
2020-02-11 15:44:56.591 22513-22576/com.cbmob.testapp W/CouchbaseLite/NETWORK: C4Socket.write() handle -> 2852069288
2020-02-11 15:44:56.592 22513-22576/com.cbmob.testapp W/CouchbaseLite/NETWORK: completedWrite(long) handle -> 2852069288, byteCount -> 121
2020-02-11 15:44:56.605 22513-22577/com.cbmob.testapp W/CouchbaseLite/NETWORK: C4Socket.completedReceive() handle -> 2852069288
2020-02-11 15:44:56.608 22513-22577/com.cbmob.testapp I/chatty: uid=10086(com.cbmob.testapp) Thread-9 identical 1 line
2020-02-11 15:44:56.612 22513-22577/com.cbmob.testapp W/CouchbaseLite/NETWORK: C4Socket.completedReceive() handle -> 2852069288
2020-02-11 15:44:56.627 22513-22513/com.cbmob.testapp I/Pull: Changed pull beer sample : Status{activityLevel=IDLE, progress=Progress{completed=0, total=0}, error=null}
2020-02-11 15:44:56.628 22513-22513/com.cbmob.testapp E/Replication Comp Log: Scheduler Completed
Clearly the document changes in the db are not being logged. From this, I am assuming that the replication is not at all happening. I am not sure how to go about debugging this. If anyone has any pointers on how this can be debugged, I would appreciate it. If needed, I could post the sync gateway logs.
If anyone has any links to any blogspots or projects which explains how to get all the pieces working together, kindly share that.
Looking forward to hearing back from people.
After a painful journey going through this whole process and getting no clue from the debug logs of emulator, I tried to run the app on a real device and it logged a error log statement which said something to the effect of not allowed to communicate with the network (I lost the exact log statement). After digging into that issue, I learnt that I was targeting API 28 and as documented here, for API >= 28, the default value for cleartextTrafficPermitted
is false
. Setting that to true
fixed the issue.
I hope this helps someone save time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With