Urban Airship Logo

Urban Airship is a popular messaging and notification service.  In part 1 of this post we’ll look at how to set up Urban Airship push notifications. In part 2 of the post we’ll use these notifications to trigger replications in Couchbase Mobile.

What you’ll need

You can use Urban Airship (UA) for free. (See the UA web site for current pricing details.) You do have to register an account.

  • An Urban Airship account
  • A Firebase account (requires a Google Login account)
  • Android Studio (or Xcode)

Part 1 – Setting up Urban Airship

Bring up an existing Android or iOS project in your IDE (or create a new one). Here I’ll illustrate using Android.

Sign in to your UA account. Navigate to the New App page. Fill in your app name. Select the platforms you want to use. (We’ll pick Android and iOS for this example.) Hitting “Save” will take you to the quickstart quide.  (If you’ve already gone through the quickstart and need a refresher on the setup, you can find the steps for Android here and for iOS here.)

Urban Airship New Application Dialog

UA quickstart

Here you’re offered a tab for each platform selected. As mentioned, we’ll focus on building for Android this time.

Follow the Urban Airship quickstart steps. I have a few tips for issues I encountered.

Steps 1 & 2 of Urban Airship quickstart

The UA guide refers to the project’s build.gradle script, but then shows modifying the module build.gradle script. I added the UA repository to my project’s gradle script, and the UA dependency to the module gradle script. That worked fine.

Look for the applicationID in the module gradle script.

Step 5 of Urban Airship quickstart

To create your own Application class, right click in the app area of the Project navigation pane and pick New > Java Class. In the popup, set the class name. Then for the Superclass enter android.app.Application.

Creating an Application subclass

Don’t forget to update your manifest file. You can use the fully qualified name of your class, or the short form that UA shows. The fully qualified form looks like this:

Step 6 of Urban Airship quickstart

UA uses Firebase Cloud Messaging (FCM). Step six has a link to further documentation by UA. This new page has detailed instructions on creating an API key for your app.

The instructions on that page under the heading ‘Configure FCM/GCM Service with Urban Airship’ are a little out of date. You’ll find the area to enter your Api Key and Package at the end of the quickstart guide now, instead of where the docs say to look.

In one place, the UA docs refer to the “Google API Project Number”. This is what FCM calls your Sender ID.

Testing

The quickstart ends with a testing area, without much instruction. If you look back at the code included in your Application subclass, you’ll see it’s enabling user notifications. To test, build your app and install it on an emulator or device. (I tried both and they worked fine.)

Urban Airship Test Panel

Enter something into the text field and click “Send Test”. You should see an icon show up in the Android notification area. Oddly, this doesn’t include the text entered into the test area.

For troubleshooting UA directs you to an obscure “Error Console” link in the lower right corner of the documentation page. The link just brought me back to the quickstart guide, unfortunately.

Wrapping up part 1

As you saw in the preceding steps, setting up Urban Airship was pretty quick. The quickstart shows how to send an alert notification. To trigger data sync in a Couchbase Lite client, we’ll want to send a silent alert instead, part 2 of this post will cover that.

Part 2 – Triggering Data Synchronization from the Cloud

In part 1 of this post you setup Urban Airship, in part 2 I will show a sample Android application built with Couchbase Lite that uses an Urban Airship push notification to trigger synchronizing data from the cloud to a mobile device. Here “the cloud” will be a Sync Gateway instance setup in a test configuration. (Couchbase Lite and Sync Gateway are both part of the Couchbase Mobile stack. You can read about Couchbase Mobile here.)

Background

Couchbase Mobile synchronizes data using unidirectional replications. You can set replications to run and end immediately once the local data is up-to-date (“one-shot”), or to listen indefinitely for new changes (“continuous”).

There are a few reasons you might want to use a service like Urban Airship to trigger synchronization instead of setting up a continous replication. For example, a continuous “pull” replication (one that retrieves data from the cloud) needs to keep a network connection open. An open connection will necessarily cause some amount of drain on the device battery, even while inactive. Ideally, an application would only open a connection when there exists changes to transfer.

Beyond that, push notification services like Urban Airship typically have a number of advanced features for addressing groups of devices. UA can give you great flexibility in managing when operations happen. Furthermore, if your app already uses a push service, that already requires its own open network connection. It makes sense to use that to trigger Couchbase Lite instead of doubling up the networking.

This example will show how to integrate Urban Airship. I’ll walk through all the necessary pieces, so you can build a fully working application.

The Application

Here’s a look at the application in action. The upper part of the image shows the app running. The lower part shows a push notification sent from the command line. When the app receives the push notification, it puts up a progress spinner, fires off a one-shot pull replication, then displays the document changes received in a text view.

To understand this example, we’ll take a look at four classes, some of the “glue” that brings them together, and show how to test the results.

Classes Required by Urban Airship

To use Urban Airship (UA), we need to implement two classes, a subclass of Autopilot, and a subclass of AirshipReceiver.

Autopilot

UA has to be initialized before use. You can do that in two ways, either call takeOff in the application’s onCreate method or by creating a subclass of Autopilot. I chose to do the latter. As we’ll see, UA has an interesting way of automatically using our subclass.

The class is simple. I don’t want to display anything in the notification bar. I use this class to turn off user notifications, and that’s all.

Here’s the full listing of CBAutoPilot.java.

To use this class, UA employs a technique unique to Android. You indicate which class to use with an entry in your Android manifest file. For my case, the entry looks like this (placed inside the application section):

This is where a bit of Android magic happens. UA includes a Content Provider class to automate the initilization. Content Providers are guaranteed to get instantiated before the application’s onCreate method gets called. UA uses that to include code to read this meta-data entry, instantiate the subclass, and call the onAirshipReady method.

AirshipReceiver

With UA initialized and ready to go, we need to provide the hooks to capture and process notifications. To do that, implement a subclass of AirshipReceiver. Again, the class is straightforward.

Here’s the full listing of CBAirshipReceiver.java.

When we get to testing the app, we’ll see how UA lets you set the alert text. I used that here provide a few different remote operations. An alert can start and stop replications. I also included the ability, by sending “reset”, to delete the database. I did that because once you replicate the data, it’s persistent on the device. Shutting down the app doesn’t reset the local database. Rather than always having to add new documents through Sync Gateway to show replication working, I added the ability to wipe the device database and start over.

You’ll notice a few other overridden methods above. Those methods are all declared abstract in the AirshipReceiver class, so we have to include at least a minimal implementation. It turns out, though, that we need to know the device channel ID to send it a message. This channel ID changes often. In a future post, I’ll show how I register the ID so a server-side application can send to the device. For now, it’s useful to log the ID so we can extract it and use it in testing.

The Application Classes

The hooks above get UA up and running, trap notifications, and trigger actions based on their contents. Now let’s take a look at the application itself.

The app consists of one Activity set up so we can see the contents of documents as they get pulled. The other class wraps some of the Couchbase Lite functionality in a helper.

The Main Activity

In the main activity, I want to show a progress bar while replications happen, then display the set of documents sent.

Here’s the full listing of MainActivity.java

The core of the code here consists of the two change listeners, one for the database, and one for replications. Each listener interface defines a single method changed.

The Document changes listener lets us track the actual document updates. A replication may change more than one document at a time. The change event returns a list of document IDs. Looping over the document IDs, we retrieve each document directly, translate the JSON contents into a string, and append it to the text to display. The change listeners are called on a background thread. To finish out, we need to manipulate the UI elements on the main thread. This is easily done with the runOnUiThread method of the Activity.

The other listener allows us to display a busy-wait spinner (indefinite progress bar) depending on the Replication state. You can read more about monitoring replication state here.

The Database Helper Class

I often wrap database functions in a helper class. Since we only need one instance of the helper, I use a singleton pattern. Just like UA, I want the helper available before the main application starts. I use the same technique of putting the code in a Content Provider.

Here’s the full listing of CBLHelper.java.

You can see this class just forms a thin wrapper. We retain an instance of the class during onCreate which becomes our singleton. Some other basic setup happens, like enabling logging and creating a database manager. I wrote an initialize method used to actually open the database, prepare the pull replication, and attach the two change listeners. Recall this is called from our Activity class. (Note: You can have more than one change listener for each type. Couchbase keeps a list of all added listeners, not just the latest one.) The other database methods just provide simple shortcuts.

A content provider has several mandatory methods to implement. We need to provide stubs for those, which you see in the last five methods.

The Android Manifest

Finally, just to show how this ties together and the various parts get exposed, I’ve included the Android manifest file for the project.

Here’s the complete listing of AndroidManifest.xml.

The UA library comes with its own manifest file. The Android build system integrates all the different manifest files to create the final one. The UA library manifest file is where you’ll find the entries for the Content Provider that bootstraps the library.

Sync Gateway

To try the app out, I used Sync Gateway with the built-in walrus database. Walrus is an in-memory database usually used just for testing. This saves the trouble of setting up a back-end Couchbase Server instance.

Here’s the complete listing of the Sync Gateway configuration file.

This tells Sync Gateway to listen only on the localhost interface, accept any cross origin requests, and enables the special GUEST with access to all channels. It’s a pretty good general purpose configuration to start with to make sure everything’s working.

You might have noticed we use 10.0.2.2 as the IP address for Sync Gateway in the Android app. The standard emulator that comes with Android Studio maps this automatically to the hosting machine’s localhost. If you use a different emulator (Genymotion is another popular one), be sure to look up what IP address to use, since they differ.

If you want to learn more about setting up Sync Gateway on your development machine, or how to work with it from the command line, take a look at this blog series.

Testing

To test everything and record the animation shown at the beginning of the blog, I run both the Android emulator and Sync Gateway on one machine. I then post push notifications to UA through their REST API.

To get something interesting prepared, I first add a document to Sync Gateway. Here’s a shell command to do that.

(Read more about this here).

With a new document in the database on Sync Gateway, and the app up and running, all that’s left is to trigger a pull replication to see the action.

Here’s the curl command to send a “start” signal. Recall I pull the value from the “alert” part of the notification to trigger actions.

You’ll need to provide your own application key and application master secret above. You also need to look at the log files to see the channel value to enter for “android_channel”. That changes fairly regularly. Unfortunately UA doesn’t do much to indicate this. If you find push notifications don’t seem to be having any effect, check the channel value.

After posting to UA, you should see a response like this.

And, finally, to reset to a blank database to try again, you can post this.

Conclusion

That’s it for getting our Android app prepared to perform replications based on push notifications. Be sure and check out this post on monitoring the Sync Gateway changes feed.

Postscript

Download Couchbase and Sync Gateway here. See our documentation for how to add Couchbase Lite to a project.

Check out more resources on our developer portal and follow us on Twitter @CouchbaseDev.

You can post questions on our forums. And we actively participate on Stack Overflow.

Hit me up on Twitter with any questions, comments, topics you’d like to see, etc. @HodGreeley.

Author

Posted by Hod Greeley, Developer Advocate, Couchbase

Hod Greeley is a Developer Advocate for Couchbase, living in Silicon Valley. He has over two decades of experience as a software engineer and engineering manager. He has worked in a variety of software fields, including computational physics and chemistry, computer and network security, finance, and mobile. Prior to joining Couchbase in 2016, Hod led developer relations for mobile at Samsung. Hod holds a Ph.D. in chemical physics from Columbia University.

One Comment

Leave a reply