Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Build an Ionic Plugin With Couchbase Lite on Android

DZone's Guide to

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.

· Database Zone ·
Free Resource

Download the Altoros NoSQL Performance Benchmark 2018. Compare top NoSQL solutions – Couchbase Server v5.5, MongoDB v3.6, and DataStax Enterprise v6 (Cassandra).

In 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.

ionic listing hotels

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.

arch android

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.

data model

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.

  1. 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
  2. Download the starter project.
  3. Unzip starter-project.zip.
  4. Open the starter-project/ directory in the JavaScript editor of your choice (for example, Visual Studio Code or WebStorm).
  5. The User Interface code is located in HotelLister/src/pages/home/.
  6. Run the following commands in your Terminal.
    cd HotelLister
    npm install
    The npm install command installs dependencies.
  7. 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.
  8. You should see an empty list view as shown below. ionic empty list

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.

  1. 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.
  2. Create a new file at cordova-plugin-hotel-lister/package.json with the following.
    {
      "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"
    }
    This file describes the plugin.
  3. 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;
  4. 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.
    package 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;
        }
    
    }
    The Cordova Plugin is instantiated when it is first called in the JavaScript WebView app. The pluginInitialized() method includes the startup code. The exec method marshals requests from the JavaScipt to the Java side. Refer to the Plugin Lifecycle documentation for more details.
  5. 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.
    cd HotelLister
    cordova plugin add ../cordova-plugin-hotel-lister/
    If successful, you should see the following in the output.
    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.

  1. Download travel-sample.cblite2.zip and drag it over to HotelLister/platforms/android/app/src/main/assets/.
  2. 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.
    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;
        }
    
    }
    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.
  3. 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/" />
  4. Next, add the following instance variable in HotelLister.java.
    private Database database;
    Add the following Java imports to the top of HotelLister.java.
    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;
  5. Then, update the initialize method in HotelLister.java with the following to set the database 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();
    }
  6. 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/
  7. Build the project.
    ionic cordova emulate android
    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.

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.

  1. Insert a new method called queryHotels in cordova-plugin-hotel-lister/src/android/HotelLister.java.
    private 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;
        }
    }
    This method queries for the addressphone and name properties of documents where the type property is hotel.
  2. 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;
    }
  3. 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');
    },
  4. You can now call the queryHotels method in the Ionic project. Add the following to the constructor method in HotelLister/src/pages/home/home.ts.
    this.platform.ready().then(() => {
      window.plugins.HotelLister.queryHotels((hotels) => {
        console.log(hotels);
        this.hotels = hotels;
      });
    });
  5. 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/
  6. Build and run.
    ionic cordova emulate android
  7. You should now see the list of hotels. ionic listing 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.

Download the whitepaper, Moving From Relational to NoSQL: How to Get Started. We’ll take you step by step through your first NoSQL project.

Topics:
database ,tutorial ,couchbase lite ,android ,cordova plugin api ,apis

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}