Hello,
I am working on Android Recipe App in which I have to implement couchbase for data sync,I am facing issue of smooth behavior and first data sync get lots of time and UI doesn’t reply as document sync. there are around 5000 document need to sync.
I create a singleton class where I am doing all couchbase related operation.
package com.breakfast.brunch.managers;
import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;
import com.breakfast.brunch.R;
import com.breakfast.brunch.models.Ingredian;
import com.breakfast.brunch.models.ShoppingModel;
import com.breakfast.brunch.pojo.ModelHelper;
import com.breakfast.brunch.utils.Constants;
import com.couchbase.lite.CouchbaseLiteException;
import com.couchbase.lite.Database;
import com.couchbase.lite.DatabaseOptions;
import com.couchbase.lite.Document;
import com.couchbase.lite.Emitter;
import com.couchbase.lite.LiveQuery;
import com.couchbase.lite.Manager;
import com.couchbase.lite.Mapper;
import com.couchbase.lite.QueryEnumerator;
import com.couchbase.lite.View;
import com.couchbase.lite.android.AndroidContext;
import com.couchbase.lite.auth.Authenticator;
import com.couchbase.lite.auth.PasswordAuthorizer;
import com.couchbase.lite.javascript.JavaScriptReplicationFilterCompiler;
import com.couchbase.lite.javascript.JavaScriptViewCompiler;
import com.couchbase.lite.replicator.Replication;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
- Created on 24/01/17.
*/
public class CBLSyncManager implements Replication.ChangeListener, Constants {
// Manager
// SharedManager
// Database of object
public static CBLSyncManager cblSyncManager;
public static Context mContext;
public Manager mManager;
public Database mDatabase;
public Database mReadableDatabase;
private String TAG = "#CBLSyncManager#";
public static CBLSyncManager getInstance(Context context) {
mContext = context;
if (cblSyncManager == null) {
cblSyncManager = new CBLSyncManager();
}
return cblSyncManager;
}
private Manager getManager() {
if (mManager == null) {
try {
AndroidContext context = new AndroidContext(mContext.getApplicationContext());
mManager = new Manager(context, Manager.DEFAULT_OPTIONS);
//install a view definition needed by the application
} catch (Exception e) {
com.couchbase.lite.util.Log.e(TAG, "Cannot create Manager object", e);
}
}
return mManager;
}
public void setManager(Manager mManager) {
this.mManager = mManager;
}
private void setLog(boolean enable) {
if (enable) {
Manager.enableLogging(TAG, com.couchbase.lite.util.Log.VERBOSE);
Manager.enableLogging(com.couchbase.lite.util.Log.TAG, com.couchbase.lite.util.Log.VERBOSE);
Manager.enableLogging(com.couchbase.lite.util.Log.TAG_SYNC_ASYNC_TASK, com.couchbase.lite.util.Log.VERBOSE);
Manager.enableLogging(com.couchbase.lite.util.Log.TAG_SYNC, com.couchbase.lite.util.Log.VERBOSE);
Manager.enableLogging(com.couchbase.lite.util.Log.TAG_QUERY, com.couchbase.lite.util.Log.VERBOSE);
Manager.enableLogging(com.couchbase.lite.util.Log.TAG_VIEW, com.couchbase.lite.util.Log.VERBOSE);
Manager.enableLogging(com.couchbase.lite.util.Log.TAG_DATABASE, com.couchbase.lite.util.Log.VERBOSE);
}
}
public void startSync() {
Authenticator auth1 = new PasswordAuthorizer("xxxxxx", "xxxxxxxxxxxx");
View.setCompiler(new JavaScriptViewCompiler());
Database.setFilterCompiler(new JavaScriptReplicationFilterCompiler());
// LiteListener liteListener = new LiteListener(getManager(), 5984, auth1);
// Thread thread = new Thread(liteListener);
// thread.start();
URL syncUrl;
try {
syncUrl = new URL(mContext.getString(R.string.syncUrl));
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
Replication pullReplication = null;
try {
pullReplication = getDatabase().createPullReplication(syncUrl);
pullReplication.setAuthenticator(auth1);
pullReplication.setContinuous(true);
List<String> channel = new ArrayList<>();
channel.add("BreakFast");
pullReplication.setChannels(channel);
pullReplication.setFilter("sync_gateway/bychannel");
pullReplication.start();
pullReplication.addChangeListener(this);
} catch (CouchbaseLiteException e) {
e.printStackTrace();
}
}
public Database getDatabase() throws CouchbaseLiteException {
String key = "password123456";
DatabaseOptions options = new DatabaseOptions();
options.setCreate(true);
options.setEncryptionKey(key);
mDatabase = getManager().openDatabase(DATABASE_NAME, options);
options.setStorageType(Manager.FORESTDB_STORAGE);
return mDatabase;
}
public Database getReadDatabase() throws CouchbaseLiteException {
String key = "password123456";
DatabaseOptions options = new DatabaseOptions();
options.setCreate(true);
options.setEncryptionKey(key);
mReadableDatabase = getManager().openDatabase(DATABASE_NAME, options);
options.setStorageType(Manager.FORESTDB_STORAGE);
return mReadableDatabase;
}
public void initFavorite(ArrayList<String> favRecipeIds) {
Map<String, Object> properties = new HashMap<>();
try {
Document document = getDatabase().getDocument(FVTRCPS);
if (getDatabase().getDocument(FVTRCPS).getProperties() == null) {
if (favRecipeIds != null) {
properties.put(RECIPEIDS, favRecipeIds);
document.putProperties(properties);
}
} else {
ArrayList<String> newIds = favRecipeIds;
properties.put(RECIPEIDS, newIds);
Map<String, Object> updatedProperties = new HashMap<String, Object>();
updatedProperties.putAll(document.getProperties());
updatedProperties.put(RECIPEIDS, newIds);
document.putProperties(updatedProperties);
Log.e(TAG, "Revision Doc: " + document.getProperties());
}
} catch (CouchbaseLiteException e) {
e.printStackTrace();
}
}
/**
* @param model
*/
public void addItemToShoppingList(ShoppingModel model) {
final String SHP_ID = SHP + model.getIngredientDocId().replace("INGR", "");
try {
// Document document = getDatabase().getDocument(SHP_ID);
ModelHelper.save(getDatabase(), model, SHP_ID);
} catch (CouchbaseLiteException e) {
e.printStackTrace();
}
}
public void initUpdateShopping(ArrayList<Ingredian> custShopIngredientList) {
Map<String, Object> properties = new HashMap<>();
try {
Document document = getDatabase().getDocument(SHPCUST);
if (getDatabase().getDocument(SHPCUST).getProperties() == null) {
//do nothing
} else {
ArrayList<Ingredian> newIds = custShopIngredientList;
properties.put(INGREDIENS, newIds);
Map<String, Object> updatedProperties = new HashMap<String, Object>();
updatedProperties.putAll(document.getProperties());
updatedProperties.put(INGREDIENS, newIds);
document.putProperties(updatedProperties);
Log.e(TAG, "Revision Doc: " + document.getProperties());
}
} catch (CouchbaseLiteException e) {
e.printStackTrace();
}
}
public void updateShoppingList(ShoppingModel shoppingModel) {
// final String SHP_ID = SHP + shoppingModel.get();
Map<String, Object> properties = new HashMap<>();
try {
Document document = getDatabase().getDocument(“shp-custom”);
Log.e(TAG, "updateShoppingList: " + document.getProperties());
properties.putAll(document.getProperties());
ObjectMapper m = new ObjectMapper();
Map<String, Object> props = m.convertValue(shoppingModel, Map.class);
try {
document.putProperties(props);
} catch (CouchbaseLiteException e) {
e.printStackTrace();
}
Log.e(TAG, "AFTER : " + document.getProperties());
} catch (CouchbaseLiteException e) {
e.printStackTrace();
}
}
public boolean hasCustomShoppingList(String documentId) {
boolean result = false;
try {
Document document = getDatabase().getDocument(documentId);
if (document.getProperty("_id") == null) {
result = false;
} else {
result = true;
}
} catch (CouchbaseLiteException e) {
e.printStackTrace();
return result;
}
return result;
}
public ArrayList<String> getFavouriteRecipeIds() {
try {
Document document = getDatabase().getDocument(FVTRCPS);
ArrayList<String> strings = (ArrayList<String>) document.getProperty(RECIPEIDS);
Log.e(TAG, "initUI: " + strings);
return strings;
} catch (CouchbaseLiteException e) {
e.printStackTrace();
return null;
}
}
@Deprecated
public void deleteShoppingList() {
try {
Document document = getDatabase().getDocument(SHPCUST);
document.delete();
Log.e(TAG, "deleteShoppingList: DONE");
} catch (CouchbaseLiteException e) {
Log.e(TAG, "deleteShoppingList: ERROR");
e.printStackTrace();
}
}
public View getDeleteShoppingView() {
View view = CBLSyncManager.getInstance(mContext).mDatabase.getView(VIEW_DELETELIST);
if (view.getMap() == null) {
Mapper mapper = new Mapper() {
public void map(Map<String, Object> document, Emitter emitter) {
if (document.get(_ID).toString().contains(SHP)) {
String docID = (String) document.get(ID);
String[] temp = new String[]{docID};
emitter.emit(temp, null);
}
}
};
view.setMap(mapper, "1.0");
}
return view;
}
QueryEnumerator enumerator;
public void deleteShoppingList(int val) {
LiveQuery mQuery = getDeleteShoppingView().createQuery().toLiveQuery();
mQuery.addChangeListener(new LiveQuery.ChangeListener() {
@Override
public void changed(final LiveQuery.ChangeEvent event) {
enumerator = event.getRows();
for (int i = 0; i < event.getRows().getCount(); i++) {
Document isShopDocuemnt = event.getRows().getRow(i).getDocument();
try {
isShopDocuemnt.delete();
Log.e(TAG, "DELETE SUCCESS");
} catch (CouchbaseLiteException e) {
Log.e(TAG, "DELETE FAIL");
e.printStackTrace();
}
}
}
});
mQuery.start();
}
public Document getItem(int position) {
return enumerator != null ? enumerator.getRow(position).getDocument() : null;
}
@Override
public void changed(Replication.ChangeEvent event) {
Replication replication = event.getSource();
com.couchbase.lite.util.Log.d(TAG, "Replication : " + replication + " changed.");
/*switch (replication.getStatus()) {
case REPLICATION_ACTIVE:
Log.e(TAG, "REPLICATION_ACTIVE");
break;
case REPLICATION_IDLE:
Log.e(TAG, "REPLICATION_IDLE");
break;
case REPLICATION_OFFLINE:
Log.e(TAG, "REPLICATION_OFFLINE");
break;
case REPLICATION_STOPPED:
Log.e(TAG, "REPLICATION_STOPPED");
break;
}
if (!replication.isRunning()) {
String msg = String.format("Replicator %s not running", replication);
// com.couchbase.lite.util.Log.d(TAG, msg);
// Log.e(TAG, “NOT RUNUNING ALL DONE”);
} else {
int processed = replication.getCompletedChangesCount();
int total = replication.getChangesCount();
String msg = String.format(“Replicator processed %d / %d”, processed, total);
// com.couchbase.lite.util.Log.d(TAG, msg);
// Log.e(TAG, “Process " + processed + " / " + total);
if (processed == total) {
// Log.e(TAG, String.format(”*** %d = %d Done", processed, total));
}
if (replication.getStatus() != Replication.ReplicationStatus.REPLICATION_ACTIVE) {
// Log.e(TAG, “changed: IN PROCESS”);
} else {
// Log.e(TAG, “ALL DONE”);
}
}
if (event.getError() != null) {
// showError(“Sync error”, event.getError());
}*/
}
}