Build an Ionic Plugin With Couchbase Lite on Android
In this tutorial, you will learn how to use Couchbase Lite to build an ionic plugin on Android a Cordova application.
Join the DZone community and get the full member experience.
Join For FreeIn this tutorial, you will learn how to use Couchbase Lite in a Cordova application.
The sample project is a Cordova web application that allows users to query for and display a list of hotels stored in a Couchbase Lite database.
Architecture
The user Interface is a web app written in Javascript using Ionic and is rendered within a WebView. The business logic and data model is written in native Java. The data model uses Couchbase Lite as the embedded data persistence layer. The Cordova Plugin API acts as the bridging layer between the JavaScript and the native Java worlds. The plugin exposes a Javascript API to the web app.
This architecture allows you to write the User Interface code once for both iOS and Android apps while leveraging Couchbase Lite’s native Android framework for data management.
Data Model
The data model for the app is very straightforward. There is one type of document: the "hotel" document which contains the details of each hotel. Those documents have a "type": "hotel"
property.
Prerequisites
This tutorial requires the following components and versions to run successfully.
- Android Studio 3.0 or above
- Android SDK 19 or above
- Couchbase Lite 2.1.0 and above
The tutorial also assumes that the reader has a basic understanding of developing apps with Cordova and Java.
Getting Started
The User Interface has already been implemented in the starter project. You will add the code to persist and query data.
- Install the Ionic and Cordova CLIs which are tools that are required for building and managing Ionic and Cordova based apps.
npm install -g ionic cordova
- Download the starter project.
- Unzip starter-project.zip.
- Open the starter-project/ directory in the JavaScript editor of your choice (for example, Visual Studio Code or WebStorm).
- The User Interface code is located in HotelLister/src/pages/home/.
- Run the following commands in your Terminal.
Thecd HotelLister npm install
npm install
command installs dependencies. - To deploy the app to an Android emulator, run the following.
ionic cordova emulate android
If you get the following error message "Could not find an installed version of Gradle either in Android Studio, or on your system to install the gradle wrapper." you can install Gradle using Homebrew with brew install gradle
. - You should see an empty list view as shown below.
In the next section, you will set up the Cordova plugin, which is the first step for establishing communication between native code and JavaScript.
Cordova Plugin Setup
With Cordova Plugins, you can write native code and have access to it from JavaScript. Plugins provide access to device and platform functionality that is ordinarily unavailable to web-based apps.
In this section, you will create a new plugin called cordova-plugin-hotel-lister to implement data persistence using Couchbase Lite’s Java API.
The plugin code will be added to the cordova-plugin-hotel-lister folder which resides alongside the HotelLister folder.
The starter project contains a file at cordova-plugin-hotel-lister/src/android/Utils.javathat will be used in a later section to unzip the pre-built database.
- Create a new file at cordova-plugin-hotel-lister/plugin.xml with the following.
<?xml version="1.0" encoding="UTF-8"?> <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-hotel-lister" version="0.0.1"> <name>cordova-plugin-hotel-lister</name> <description>An Cordova plugin for the Hotel Lister application to implement data persistence using Couchbase Lite.</description> <license>Couchbase CE / https://www.couchbase.com/binaries/content/assets/website/legal/ce-license-agreement.pdf</license> <engines> <engine name="cordova" version=">=3.0.0"/> </engines> <js-module src="www/hotel-lister.js" name="HotelLister"> <clobbers target="window.plugins.HotelLister" /> </js-module> <platform name="android"> <config-file target="res/xml/config.xml" parent="/*"> <feature name="HotelLister"> <param name="android-package" value="com.hotellister.HotelLister"/> </feature> </config-file> <source-file src="src/android/HotelLister.java" target-dir="src/com/hotellister/" /> <source-file src="src/android/Utils.java" target-dir="src/com/hotellister/" /> </platform> </plugin>
- The
id="cordova-plugin-hotel-lister"
attribute is the plugin name which will be used later to import it in the Ionic project. - The
<js-module></js-module>
XML tag declares the location of the file that will declare the JavaScript interface. - The
<platform name="android"></platform>
XML tag declares the location of the Java files to hold the native code.
- The
- Create a new file at cordova-plugin-hotel-lister/package.json with the following.
This file describes the plugin.{ "name": "cordova-plugin-hotel-lister", "version": "0.0.1", "description": "A Cordova plugin for the Hotel Lister app.", "cordova": { "id": "cordova-plugin-hotel-lister", "platforms": [ "android", "ios" ] }, "engines": [ { "name": "cordova", "version": ">=3.0.0" } ], "author": "Couchbase <mobile@couchbase.com>", "license": "Couchbase CE / https://www.couchbase.com/binaries/content/assets/website/legal/ce-license-agreement.pdf" }
- Create a new file at cordova-plugin-hotel-lister/www/hotel-lister.js. This file defines the JS API with which a Cordova/Ionic web app may interact with this plugin. Generally, this means that the plugin binds to the window element and by doing so, grants access to its parent project through simple JavaScript references. Add the following to your hotel-lister.js file:
var exec = require('cordova/exec'); var hotelLister = { /* code will be added here later */ }; module.exports = hotelLister;
- Create a new file at cordova-plugin-hotel-lister/src/android/HotelLister.java with the following. This file provides the native Java implementation corresponding to the APIs defined in hotel-lister.js.
The Cordova Plugin is instantiated when it is first called in the JavaScript WebView app. Thepackage com.hotellister; import android.content.Context; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaInterface; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CordovaWebView; import org.json.JSONArray; import java.util.ArrayList; import java.util.List; import java.util.Map; public class HotelLister extends CordovaPlugin { @Override public void initialize(CordovaInterface cordova, CordovaWebView webView) { super.initialize(cordova, webView); } @Override public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) { return false; } }
pluginInitialized()
method includes the startup code. Theexec
method marshals requests from the JavaScipt to the Java side. Refer to the Plugin Lifecycle documentation for more details. - To verify that your plugin is ready to work as expected, you have to install it in your HotelLister project. To do so, run the following commands from the root of the starter-project folder.
If successful, you should see the following in the output.cd HotelLister cordova plugin add ../cordova-plugin-hotel-lister/
Adding cordova-plugin-hotel-lister to package.json Saved plugin info for "cordova-plugin-hotel-lister" to config.xml
Couchbase Lite Setup
To import Couchbase Lite in the Android Studio project, add it as a gradle dependency in the dependencies
section of HotelLister/platforms/android/app/build.gradle.
dependencies {
implementation fileTree(dir: 'libs', include: '*.jar')
// SUB-PROJECT DEPENDENCIES START
implementation(project(path: ":CordovaLib"))
compile "com.android.support:support-annotations:27.+"
// SUB-PROJECT DEPENDENCIES END
implementation 'com.couchbase.lite:couchbase-lite-android:2.1.0'
}
Database Setup
In our example, we will start with a pre-built Couchbase Lite database that contains a bunch of hotel documents. We will make our queries against the documents in this database. Note that in a real-world application, the data could be synced down from other Couchbase Lite clients or from Sync Gateway in the cloud.
The pre-built database needs to be added to the Android Studio project.
- Download travel-sample.cblite2.zip and drag it over to HotelLister/platforms/android/app/src/main/assets/.
- We will use the singleton pattern to setup the database instance. Create a new file at cordova-plugin-hotel-lister/src/android/DatabaseManager.java and insert the following.
You first check if a database named "travel-sample" exists. If it doesn’t exist, the travel-sample.cblite2 database file that was bundled with the app is copied to the default Couchbase Lite directory. The database is then opened and the database instance is set.package com.hotellister; import android.content.Context; import com.couchbase.lite.CouchbaseLiteException; import com.couchbase.lite.Database; import com.couchbase.lite.DatabaseConfiguration; import com.couchbase.lite.FullTextIndex; import com.couchbase.lite.FullTextIndexItem; import com.couchbase.lite.IndexBuilder; public class DatabaseManager { private static String DB_NAME = "travel-sample"; private static Database database; private static DatabaseManager instance = null; private DatabaseManager(Context context) { if (!Database.exists("travel-sample", context.getFilesDir())) { String assetFile = String.format("%s.cblite2.zip", DB_NAME); Utils.installPrebuiltDatabase(context, assetFile); } DatabaseConfiguration configuration = new DatabaseConfiguration(context); try { database = new Database(DB_NAME, configuration); } catch (CouchbaseLiteException e) { e.printStackTrace(); } } public static DatabaseManager getSharedInstance(Context context) { if (instance == null) { instance = new DatabaseManager(context); } return instance; } public static Database getDatabase() { if (instance == null) { try { throw new Exception("Must call getSharedInstance first"); } catch (Exception e) { e.printStackTrace(); } } return database; } }
- When adding a new Java file, it must be referenced in the plugin’s configuration file. Insert the following as a child to the
<platform name="android"></platform>
element in cordova-plugin-hotel-lister/plugin.xml.<source-file src="src/android/DatabaseManager.java" target-dir="src/com/hotellister/" />
- Next, add the following instance variable in HotelLister.java.
Add the following Java imports to the top of HotelLister.java.private Database database;
import com.couchbase.lite.CouchbaseLiteException; import com.couchbase.lite.DataSource; import com.couchbase.lite.Database; import com.couchbase.lite.Expression; import com.couchbase.lite.Meta; import com.couchbase.lite.Query; import com.couchbase.lite.QueryBuilder; import com.couchbase.lite.Result; import com.couchbase.lite.ResultSet; import com.couchbase.lite.SelectResult;
- Then, update the
initialize
method in HotelLister.java with the following to set thedatabase
instance property.@Override public void initialize(CordovaInterface cordova, CordovaWebView webView) { super.initialize(cordova, webView); Context context = cordova.getContext(); DatabaseManager.getSharedInstance(context); this.database = DatabaseManager.getDatabase(); }
- To test your changes, you must re-install the Cordova plugin from cordova-plugin-hotel-lister to HotelLister. Run the following commands from the root of the starter-project folder.
cd HotelLister cordova plugin rm cordova-plugin-hotel-lister cordova plugin add ../cordova-plugin-hotel-lister/
- Build the project.
The application should run successfully. You will still see an empty screen because at this stage, the Couchbase Lite database is initialized but you haven’t run any queries to fetch data from the database.ionic cordova emulate android
In the next section, you will use this Database variable to query hotels from the pre-built database.
Listing Hotels
In this section, you will add the functionality to list hotels from the database.
- Insert a new method called
queryHotels
in cordova-plugin-hotel-lister/src/android/HotelLister.java.
This method queries for theprivate List<Result> queryHotels() { String DOC_TYPE = "hotel"; Query query = QueryBuilder .select( SelectResult.expression(Meta.id), SelectResult.property("address"), SelectResult.property("phone"), SelectResult.property("name") ) .from(DataSource.database(database)) .where( Expression.property("type") .equalTo(Expression.string(DOC_TYPE)) ); try { ResultSet resultSet = query.execute(); return resultSet.allResults(); } catch (CouchbaseLiteException e) { e.printStackTrace(); return null; } }
address
,phone
andname
properties of documents where thetype
property ishotel
. - You can now call this method from the
execute
method in cordova-plugin-hotel-lister/src/android/HotelLister.java. Whatever is dispatched to the plugin with JavaScript’s exec function is passed into the plugin class’s execute method.@Override public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) { if ("queryHotels".equals(action)) { List<Result> resultList = queryHotels(); ArrayList<Map<String,Object>> arrayList = new ArrayList<>(); assert resultList != null; for (Result result : resultList) { Map<String,Object> map = result.toMap(); arrayList.add(map); } JSONArray jsonArray = new JSONArray(arrayList); callbackContext.success(jsonArray); return true; } return false; }
- Next, you will update the plugin’s JavaScript interface. In cordova-plugin-hotel-lister/www/hotel-lister.js, replace the
/* code will be added here later */
comment with the following.queryHotels: function(successCallback, errorCallback) { exec(successCallback, errorCallback, 'HotelLister', 'queryHotels'); },
- You can now call the
queryHotels
method in the Ionic project. Add the following to theconstructor
method in HotelLister/src/pages/home/home.ts.this.platform.ready().then(() => { window.plugins.HotelLister.queryHotels((hotels) => { console.log(hotels); this.hotels = hotels; }); });
- To test your changes, you must re-install the Cordova plugin from cordova-plugin-hotel-lister to HotelLister. Run the following commands from the root of the start-project folder
cd HotelLister cordova plugin rm cordova-plugin-hotel-lister cordova plugin add ../cordova-plugin-hotel-lister/
- Build and run.
ionic cordova emulate android
- You should now see the list of hotels.
Conclusion
Well done! You have learned how to create a Cordova plugin to use Couchbase Lite’s native APIs and import the plugin in an Ionic project!
You can find a working copy of the completed project in the final project zip file. To build and run the final project, follow the instructions outlined in the Getting Started section.
Published at DZone with permission of James Nocentini, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments