Couchbase Lite Android: CBLReplication customProperties alternative in Android

Hello,
Can you please tell alternative to adding custom properties in replication for Android?

/** An optional JSON-compatible dictionary of extra properties for the replicator. /
@property (nonatomic, copy, nullable) CBLJSONDict
customProperties;

I want to add reset properties to start replication from scratch after purge.

I do this in iOS as below
replication?.customProperties = [“reset” : “reset”]

I referred to below link for iOS

Sorry, that isn’t implemented yet on Android.

Hi Jens,
Thank you for your reply. Does this mean that for now we must not purge document in Android if we may require it in future for that user?

You can create a replication that pulls only the specific documents that were purged. (Set the documentIDs property on the replication.)

Thanks again. However my use case is, user subscribe to channel and download all docs from that channel.
When User wants to unsubscribe the channel I purge all docs. Now I dont have all document ids for that channel so I can not re-download in Android by setting documentIDs property. (In iOS it is simple, reset the replication)

For this use case any other workaround for Android?

I don’t know. I’ll ping @hideki, who works on Android.

@pvaghasi,
If you re-subscribe the channel, CBL Android could replicate docs again. However, I have never confirmed this scenario.

Hi @Hideki,
When I purge docs from database and try to resubscribe to the channel, replication is not pulling up docs.

in iOS this works if I add reset to custom properties.

Can you please suggest how can I achieve this for android?

I am attaching two log files.

  1. Fresh replication of a particular channel works fine.
  2. After Purging all docs from that channel, I try to replicate same channel. Does not work as it starts from last saved sequence. Ideally there should be some method to remove database saved last sequence for given channel.

logs.zip (4.5 KB)

Hi @pvaghasi,
If CBL Android does not replicate the purged documents, it seems it is a bug. Can you file the ticket? https://github.com/couchbase/couchbase-lite-java-core/issues
Thanks!

To me it seems like normal behavior. Purging documents means that they will be obliterated without notifying anyone else (local only). So in terms of the replicator, it has already passed those sequences and doesn’t need to process them again. If there is an update to those documents, then the pull will get the updates but the replicator won’t go back in time to get the already processed revisions. In iOS, you are effectively telling the replication to start over from scratch by using the reset property. Does Android have a remote UUID property? If so, you can change that as an alternative as it will be considered a new replication that needs to start over from the beginning.

Sorry I skipped to read if I add.....

Currently CBL Android does not support custom property for replicator. Ticket is already filed into the repo.

Following is advise from my co-worker. (Workaround)

  • You might try to add the random channel name to channel name array. It could generate new remote check point id. It should allow to re-replicate all data.
  • Or you could create new database with new name, or delete the database and create new database.

Thanks,
hideki

Hi @hideki @borrrden
Both these workarounds are not feasible as There are lot of events that one user can follow, un-follow and try to follow it again. So database creation/recreation is not possible as we need to migrate all data (other followed events) every time for such a simple requirement.

Each event has unique channel (called Event ID) which end users share with different other end users who wish to follow it so random name also will not be doable.

Is there any possibility of implementing this in Android?
Currently as a workaround when user un-follow an event, we hide it from UI but those docs still takes memory which is obviously not scalable and this will easily be biggest blocker for us.

I will be more than happy to make a Pull Request on Android if you guide me how to do this? I am sure it will not be complicated.

Hi @pvaghasi,

We have planned to implement the Replicator custom properties feature to CBL Android. But I can not say when we will be able to implement this.

Short term solution could be you could port the implementation from CBL iOS to CBL Android/Java. We are happy if you could send us the PR for this.

Thanks!

Hi @hideki,
I added 1 custom property support (Currently only 1 to Reset, Others can be added in enum) in couchbase-lite-java-core and trying to test it by using submodules in couchbase-lite-android repo.

Now I have added this new couchbase-lite-android with submodules, into my app as module. Upto now everything is fine, I am able to build the project.

When I run the app, At runtime I am facing issues.

When I use SQLITE Storage engine, below error is thrown.

java.lang.UnsatisfiedLinkError: No implementation found for long com.couchbase.lite.internal.database.sqlite.SQLiteConnection.nativeOpen(java.lang.String, int, java.lang.String, boolean, boolean) (tried Java_com_couchbase_lite_internal_database_sqlite_SQLiteConnection_nativeOpen and Java_com_couchbase_lite_internal_database_sqlite_SQLiteConnection_nativeOpen__Ljava_lang_String_2ILjava_lang_String_2ZZ)

AND When I use ForestDB I face below error.

java.lang.UnsatisfiedLinkError: No implementation found for long com.couchbase.cbforest.Database._open(java.lang.String, int, int, byte[]) (tried Java_com_couchbase_cbforest_Database__1open and Java_com_couchbase_cbforest_Database__1open__Ljava_lang_String_2II_3B)

I have NDK installed and ndk.dir is set in local.properties.

Can you please help here so that I can test and send pull request.

@pvaghasi

When you create the submodule, do you set up a dependency on SQLite/ForestDB? It looks like they are not getting pulled in automatically.

Hi @hod.greeley
Thanks for your reply, Yes those are added in my project.

compile 'com.couchbase.lite:couchbase-lite-java-sqlcipher:1.3.1'
compile 'com.couchbase.lite:couchbase-lite-java-sqlite-custom:1.3.1'
compile 'com.couchbase.lite:couchbase-lite-java-forestdb:1.3.1'

I have tried in Emulator as well as on real device (API 22). Please find attached log file.

crash.txt.zip (1.9 KB)

Hi @pvaghasi,

I can’t download the attachment for some reason. Can you upload it again?

Here you go…
crash.txt.zip (1.9 KB)

Still can’t retrieve it. I’m getting a 404 error (page not found). Are you able to follow the link yourself?

I cant follow it as well. Pasting the log file here itself

12-30 10:45:48.730 10125-10125/com.happyfall.kamero W/System.err: Library not found: /native/linux/armv7l/libCouchbaseLiteJavaForestDB.so
12-30 10:45:48.730 10125-10125/com.happyfall.kamero W/System.err: Error loading library: CouchbaseLiteJavaForestDB
12-30 10:45:48.730 10125-10125/com.happyfall.kamero W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method ‘java.lang.String java.io.File.getAbsolutePath()’ on a null object reference
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at com.couchbase.lite.util.NativeLibUtils.loadLibrary(NativeLibUtils.java:45)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at com.couchbase.lite.store.ForestDBStore.(ForestDBStore.java:75)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at java.lang.Class.classForName(Native Method)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at java.lang.Class.forName(Class.java:309)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at java.lang.Class.forName(Class.java:273)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at com.couchbase.lite.Database.createStoreInstance(Database.java:1236)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at com.couchbase.lite.Database.open(Database.java:1292)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at com.couchbase.lite.Manager.openDatabase(Manager.java:334)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at com.happyfall.kamero._4_couchbase.database.CouchDatabase.getDatabase(CouchDatabase.java:42)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at com.happyfall.kamero._4_couchbase.CouchApp.(CouchApp.java:27)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at com.happyfall.kamero._4_couchbase.CouchApp.(CouchApp.java:20)
12-30 10:45:48.733 10125-10125/com.happyfall.kamero W/System.err: at com.happyfall.kamero._4_couchbase.replication.ContinuousReplication.(ContinuousReplication.java:24)
12-30 10:45:48.734 10125-10125/com.happyfall.kamero W/System.err: at com.happyfall.kamero._4_couchbase.replication.ContinuousReplication.(ContinuousReplication.java:19)
12-30 10:45:48.734 10125-10125/com.happyfall.kamero W/System.err: at com.happyfall.kamero._2_login._2_facebook.LoginManager.userLoggedIn(LoginManager.java:191)
12-30 10:45:48.734 10125-10125/com.happyfall.kamero W/System.err: at com.happyfall.kamero._2_login._2_facebook.LoginManager.(LoginManager.java:78)
12-30 10:45:48.734 10125-10125/com.happyfall.kamero W/System.err: at com.happyfall.kamero._2_login._2_facebook.LoginManager.(LoginManager.java:31)
12-30 10:45:48.734 10125-10125/com.happyfall.kamero W/System.err: at com.happyfall.kamero._1_init.KameroApp.onCreate(KameroApp.java:49)
12-30 10:45:48.734 10125-10125/com.happyfall.kamero W/System.err: at com.android.tools.fd.runtime.BootstrapApplication.onCreate(BootstrapApplication.java:370)
12-30 10:45:48.735 10125-10125/com.happyfall.kamero W/System.err: at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1035)
12-30 10:45:48.735 10125-10125/com.happyfall.kamero W/System.err: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4638)
12-30 10:45:48.735 10125-10125/com.happyfall.kamero W/System.err: at android.app.ActivityThread.access$1500(ActivityThread.java:155)
12-30 10:45:48.735 10125-10125/com.happyfall.kamero W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1378)
12-30 10:45:48.735 10125-10125/com.happyfall.kamero W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
12-30 10:45:48.735 10125-10125/com.happyfall.kamero W/System.err: at android.os.Looper.loop(Looper.java:135)
12-30 10:45:48.735 10125-10125/com.happyfall.kamero W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5343)
12-30 10:45:48.735 10125-10125/com.happyfall.kamero W/System.err: at java.lang.reflect.Method.invoke(Native Method)
12-30 10:45:48.738 10125-10125/com.happyfall.kamero W/System.err: at java.lang.reflect.Method.invoke(Method.java:372)
12-30 10:45:48.738 10125-10125/com.happyfall.kamero W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
12-30 10:45:48.739 10125-10125/com.happyfall.kamero W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
12-30 10:45:48.739 10125-10125/com.happyfall.kamero E/Database: ERROR: Failed to load CouchbaseLiteJavaForestDB
12-30 10:45:48.798 10125-10125/com.happyfall.kamero E/art: No implementation found for long com.couchbase.cbforest.Database._open(java.lang.String, int, int, byte[]) (tried Java_com_couchbase_cbforest_Database__1open and Java_com_couchbase_cbforest_Database__1open__Ljava_lang_String_2II_3B)
12-30 10:45:48.799 10125-10125/com.happyfall.kamero D/AndroidRuntime: Shutting down VM

--------- beginning of crash
12-30 10:45:48.800 10125-10125/com.happyfall.kamero E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.happyfall.kamero, PID: 10125
java.lang.UnsatisfiedLinkError: No implementation found for long com.couchbase.cbforest.Database._open(java.lang.String, int, int, byte[]) (tried Java_com_couchbase_cbforest_Database__1open and Java_com_couchbase_cbforest_Database__1open__Ljava_lang_String_2II_3B)
at com.couchbase.cbforest.Database._open(Native Method)
at com.couchbase.cbforest.Database.(Database.java:26)
at com.couchbase.lite.store.ForestDBStore.open(ForestDBStore.java:158)
at com.couchbase.lite.Database.open(Database.java:1331)
at com.couchbase.lite.Manager.openDatabase(Manager.java:334)
at com.happyfall.kamero._4_couchbase.database.CouchDatabase.getDatabase(CouchDatabase.java:42)
at com.happyfall.kamero._4_couchbase.CouchApp.(CouchApp.java:27)
at com.happyfall.kamero._4_couchbase.CouchApp.(CouchApp.java:20)
at com.happyfall.kamero._4_couchbase.replication.ContinuousReplication.(ContinuousReplication.java:24)
at com.happyfall.kamero._4_couchbase.replication.ContinuousReplication.(ContinuousReplication.java:19)
at com.happyfall.kamero._2_login._2_facebook.LoginManager.userLoggedIn(LoginManager.java:191)
at com.happyfall.kamero._2_login.2_facebook.LoginManager.(LoginManager.java:78)
at com.happyfall.kamero.2_login.2_facebook.LoginManager.(LoginManager.java:31)
at com.happyfall.kamero.1_init.KameroApp.onCreate(KameroApp.java:49)
at com.android.tools.fd.runtime.BootstrapApplication.onCreate(BootstrapApplication.java:370)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1035)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4638)
at android.app.ActivityThread.access$1500(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1378)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
12-30 10:45:54.931 10125-10137/com.happyfall.kamero E/art: No implementation found for void com.couchbase.cbforest.Database.free() (tried Java_com_couchbase_cbforest_Database_free and Java_com_couchbase_cbforest_Database_free
)
12-30 10:45:54.931 10125-10137/com.happyfall.kamero E/System: Uncaught exception thrown by finalizer
12-30 10:45:54.931 10125-10137/com.happyfall.kamero E/System: java.lang.UnsatisfiedLinkError: No implementation found for void com.couchbase.cbforest.Database.free() (tried Java_com_couchbase_cbforest_Database_free and Java_com_couchbase_cbforest_Database_free
)
at com.couchbase.cbforest.Database.free(Native Method)
at com.couchbase.cbforest.Database.finalize(Database.java:70)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:191)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:174)
at java.lang.Thread.run(Thread.java:818)