PhoneGap

Add Xtremepush to both iOS and Android apps built with Cordova, PhoneGap or Ionic

Xtremepush supports push notifications for iOS devices via Apple's Push Notification Service (APNs) and for Android devices via Google’s FCM (Firebase Cloud Messaging for Android) service. This page contains PhoneGap specific instructions but you will need to connect your iOS and Android app to the platform separately.

👍

To integrate successfully you will need to have your xtremepush App Key, APNS certs for iOS and, Firebase Sender ID and Server Key for Android. These are used to connect your app to the platform and the Apple and Google push services. You will find links to documentation on connecting to the platform below:

Android

After you retrieve the google-services.json file for your app from FCM you should add it into the platforms/android/app directory.

744

Full Cordova integration guides are given for iOS and Android below.

Installing the Xtremepush plugin

  1. In a terminal navigate to your project directory
  2. From a terminal, navigate to your application directory and add the plugin with the following command:
cordova plugin add https://github.com/xtremepush/XtremePush-Phonegap
  1. Now edit your index.js file to register with the Xtremepush server on a deviceready event, taking care to switch APP_KEY and FCM_PROJECT_NUMBER to actual values.
    An orientationchange listener can also be added, to allow rotation of in-app messages, as seen below:
var app = {
    // Application Constructor
    initialize: function() {
        this.bindEvents();
    },
    // Bind Event Listeners
    //
    // Bind any events that are required on startup. Common events are:
    // 'load', 'deviceready', 'offline', and 'online'.
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
        window.addEventListener('orientationchange', doOnOrientationChange);
    },
    // deviceready Event Handler
    //
    // The scope of 'this' is the event. In order to call the 'receivedEvent'
    // function, we must explicitly call 'app.receivedEvent(...);'
    onDeviceReady: function() {
        registerXtremePush();
    }
};

function registerXtremePush(){
    XtremePush.register({    
        appKey: "APP_KEY",
        debugLogsEnabled: true,
        inappMessagingEnabled: true,
        ios: {
            pushPermissionsRequest: true,
            
            //if using locations
            locationsEnabled: true,
            beaconsEnabled: true,
            locationsPermissionsRequest: true,
        },
        android: {
            gcmProjectNumber: "GCM_PROJECT_NUMBER",
            
            //if using locations
            geoEnabled: true,
            beaconsEnabled: true
        }
    });
}

function doOnOrientationChange() {
    XtremePush.onConfigChanged();
}

app.initialize();

You will need to add NSBluetoothPeripheralUsageDescription to your config.xml file under the iOS section. It is a required usage description you have to add to your app if it includes CoreBluetooth (even if core bluetooth is not actively used). The Xtremepush iOS SDK currently requires you to do that. See docs here for more information.

Note: If you are using locations you will need to add the following to your config.xml file under the iOS section:

<platform name="ios">
 <allow-intent href="itms:*" />
 <allow-intent href="itms-apps:*" />
 <config-file parent="NSLocationAlwaysUsageDescription" target="*-Info.plist">
 <string>We use Location services to send you relevant information, when and where you need it</string>
 </config-file>
 <config-file parent="NSLocationAlwaysAndWhenInUseUsageDescription" target="*-Info.plist">
 <string>We use Location services to send you relevant information, when and where you need it</string>
 </config-file>
 <config-file parent="NSLocationWhenInUseUsageDescription" target="*-Info.plist">
 <string>We use Location services to send you relevant information, when and where you need it</string>
 </config-file>
 <config-file parent="NSBluetoothAlwaysUsageDescription" target="*-Info.plist">
 <string>We use Bluetooth services to send you relevant information, when and where you need it</string>
 </config-file>
 </platform>

These are the messages that will show to the user when they are shown the prompt for granting location and bluetooth permission. In the example above we have added a placeholder text, but this can be changed to something more relevant which allows you to relate why you are asking your users to grant location access.

At this point, your basic Xtremepush integration is complete. If you build your project now, the app should register with the Xtremepush platform and you should be able to start sending campaigns to your device.

👍

Make sure you set the user ID

It is recommended that at this stage you use our SDK method to set user IDs by following our dedicated guide to ensure devices can be associated and targeted in your campaigns by your own unique identifier.

Sample

If you have any difficulty in configuring the implementation, a sample app can be built using the following two files as a starting point:

index.html

<!DOCTYPE html>
<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at
 
 http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 -->
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' gap:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
            <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
            <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
            <meta name="msapplication-tap-highlight" content="no" />
            <title>Hello World</title>
            <script async src='/cdn-cgi/bm/cv/669835187/api.js'></script></head>
    
    
    <body>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
        
        <div>
            <h1>Apache Cordova</h1>
            <button onclick="XtremePush.hitTag('test-tag')"> Hit Tag </button> <br><br>
            <button onclick="XtremePush.hitTag('test-tag-with-value', 'value')"> Hit Tag With Value </button> <br><br>
            <button onclick="XtremePush.sendTags()"> Send Tags </button> <br><br>
            <button onclick="XtremePush.hitImpression('test-impression')"> Hit Impression </button> <br><br>
            <button onclick="XtremePush.sendImpressions()"> Send Impressions </button> <br><br>
            <button onclick="XtremePush.hitEvent('test-event')"> Hit Event </button> <br><br>
            <button onclick="XtremePush.hitEvent('test-event2', 'string')"> Hit Event Value </button> <br><br>
            <button onclick="XtremePush.hitEvent('test-event2', {test:'value'})"> Hit Event Values </button> <br><br>
            <button onclick="XtremePush.setExternalId('mktest2')"> Set External ID </button> <br><br>
            <button onclick="deviceInfo()"> Get Device Info </button> <br><br>
            <button onclick="XtremePush.requestPushPermissions()"> Request Push Permission </button> <br><br>
            <button onclick="XtremePush.requestLocationsPermissions()"> Request Locations Permissions </button> <br><br>
            <button onclick="XtremePush.setSubscription(true)"> Set Subscription </button> <br><br>
            <button onclick="XtremePush.setSubscription(false)"> Unset Subscription </button> <br><br>
            <button onclick="XtremePush.unregisterForRemoteNotifications()"> Unregister for Remote Notifications (iOS only) </button> <br><br>
            <button onclick="XtremePush.openInbox()">Open Inbox</button> <br><br>
            <button onclick="XtremePush.getInboxBadge()"> Get Inbox Badge </button> <br><br>
        </div>
    <script type="text/javascript">(function(){window['__CF$cv$params']={r:'633e7dd36c7d34d2',m:'8233b0701de8ff1fbccfc6a51710c3f295914840-1616406372-1800-AYzMOccKYVJx7hvEoy1CSURSAAy3jV8TLxJRDzxxumgudB2bcVHria2ZLmh+LVvttLN0DK24sw0/fyIpg2tM1TT5P5fizNSdhc8FCV7jlbDcpiQA4D8v2HlAhcZdMl8Pm7NqO/PRQN5L7TsjWRSQPiEbwRv7m0t7l9VVusPEeEXb',s:[0x32542a7c11,0x6252694269],}})();</script></body>
</html>

index.js

var app = {
   // Application Constructor
   initialize: function() {
       this.bindEvents();
   },
   // Bind Event Listeners
   //
   // Bind any events that are required on startup. Common events are:
   // 'load', 'deviceready', 'offline', and 'online'.
   bindEvents: function() {
       document.addEventListener('deviceready', this.onDeviceReady, false);
       window.addEventListener('orientationchange', doOnOrientationChange);
   },
   // deviceready Event Handler
   //
   // The scope of 'this' is the event. In order to call the 'receivedEvent'
   // function, we must explicitly call 'app.receivedEvent(...);'
   onDeviceReady: function() {
       registerXtremePush();
   }
};

function registerXtremePush() {
    XtremePush.register({
            appKey:"AppKey",
            impressionsBatchingEnabled:true,
            inappMessagingEnabled:true,
            tagsBatchingEnabled:true,
            inboxEnabled:true,
            messageResponseCallback : "onMessageResponse",
            inboxBadgeCallback: "onInboxBadgeUpdate",
            deeplinkCallback : "onDeeplinkReceived",
            ios:{
                locationsEnabled:true,
                locationsPermissionsRequest:true,
                pushPermissionsRequest:true
            },
            android:
            {
                gcmProjectNumber:"SenderID", 
                geoEnabled:true,
                beaconsEnabled:true,
                locationsPermissionsRequest: true
            }
        });
}

function doOnOrientationChange() {
     XtremePush.onConfigChanged();
}

function onMessageResponse(data) {
    console.log("Message Response " + JSON.stringify(data));
}

function onInboxBadgeUpdate(data){
    console.log("Inbox badge update " + data);
}

function onDeeplinkReceived(data){
    console.log("Deeplink Received " + data);
}

function deviceInfo() {
    XtremePush.deviceInfo(function(data){
        console.log(data);
    });
}

app.initialize();

A full list of our JavaScript functions and their parameters can be found in the xtremepush.js plugin file.

Additional options

Tagging, events and special cases

Tagging and events can then be implemented in your app as follows:

Sample button showing how to hit an event (for triggering campaigns):

<button onclick="XtremePush.hitEvent('test-event')"> Hit Event </button>

Sample button showing how to hit a tag (for analytics/segmentation purposes):

<button onclick="XtremePush.hitTag('test-tag')"> Hit Tag </button>

There are special cases where you may want to send values, such as string or maps, with an event hit. To do that you can use this structure:

Sample button showing how to call hitEventWithValue (Value can be a String or a Map)

<button onclick="hitEventWithValue()"> Hit Event With Value </button>

And in the JS file:

function hitEventWithValue() {
    //var stringOrMap = {0: "number0", 1: "number1"};
    //var stringOrMap = "numbers";
    XtremePush.hitEventWithValue('eventName', stringOrMap);
}

Callback Functions

messageResponseCallback, deeplinkCallback and inboxBadgeCallback options allow you to link JavaScript functions, defined in the JavaScript files of your project, to the Xtremepush SDK. These functions will then be called by the SDK when particular events happen. After your functions have been created, you can set them with the XtremePush.register() function, using each of the following optional settings:

messageResponseCallback : "onMessageResponse",
inboxBadgeCallback: "inboxBadgeCallbackFunction",
deeplinkCallback : "onDeeplinkReceived",

They are called to be executed in special cases as explained below:

messageResponseCallback

A basic implementation is shown below.

function onMessageResponse(data) {
    let jo = JSON.parse(JSON.stringify(data));
    console.log(JSON.stringify(jo));
    
    if (jo.response.type == = "present") {

    } else if (jo.response.type == = "click") {

    } else if (jo.response.type == = "dismiss") {

    }
}

The response.type variable shown above can be either present, click or dismiss.

  • Present: when a push notification is received and the app is in the foreground
  • Click: when a message is clicked
  • Dismiss: when a message is dismissed

Below is a complete example of custom notification handling. It does multiple things:

  • Shows a custom dialog when a push message is received in the foreground
  • Opens an article page when a message is clicked
  • Saves information when one of the message buttons is clicked
function onMessageResponse(data) {
    let jo = JSON.parse(JSON.stringify(data));

    // When app is received in the foreground show an alert
    if (jo.response.type == = "present") {
        console.log(JSON.stringify(jo));
        openArticle(jo.message.data.articleId);

    //when the user clicks on a message 
    } else if (jo.response.type == = "click") {
        //default click action
        if (!jo.response.hasOwnProperty('action')) {
            openArticle(jo.message.data.articleId);

        //action for specific button click
        } else {
            if (jo.response.action == = "like") {
                likeArticle(jo.message.data.articleId);
            } else if (jo.response.action == = "share") {
                shareArticle(jo.message.data.articleId);
            }
        }

    //show alert if dismiss button click
    } else if (jo.response.type == = "dismiss") {
        alert("message dismiss");
    }
}

inboxBadgeCallback

It happens when the badge number updates. The badge number is checked when:

  • New push message arrives
  • Application is started
  • Inbox window is closed

An example is shown below:

function onInboxBadgeUpdate(data){
    alert ('Inbox badge update ' + data);
}

deeplinkCallback

It happens when a message with the click action Go to deeplink is clicked. See our guide for deeplinks for more information.

An example is shown below:

function onDeeplinkReceived(data){
    alert("deeplink Received "+data);
}

Foreground Notification Handling

It is important to define the right behaviour for the situation when a push notification is received in the foreground. You don't want to interrupt the user workflow but may still want to deliver important information to the user.
The default behaviour on both iOS and Android is to show an OS style notification, but this can be changed, by adding the payload with the key 'foreground' and value 'false' to your campaign.

607

Now when the push is received, should the app be in the foreground, the notification will not be displayed.

Advanced options

Attributions

If you would like Xtremepush to collect IDFA/Ad ID and attribution data in your app, we have a repository branch of the plugin that copies the required frameworks into your app. This can be installed using the following command:

cordova plugin add https://github.com/xtremepush/XtremePush-Phonegap#master+attributions

To enable the collection functionality, the attributionsEnabled parameter in the XtremePush.register() function must also be set with a value of true.

Remove location services

If you would like to remove the geo-location and beacon frameworks and services from your app, please use the following command when installing the plugin:

cordova plugin add  https://github.com/xtremepush/XtremePush-Phonegap#master-geo-beacon

Inbox

The inbox feature can be turned on in your app by adding the following to your XtremePush.register() function:

inboxEnabled: true

Here is a sample button showing how to open inbox

<button onclick="XtremePush.openInbox()">Open Inbox</button>

If you want to use the inbox badge functionality please use the following in your XtremePush.register() function:

inboxBadgeCallback: "onInboxBadgeUpdate"

Here is a sample button showing how to retrieve the latest badge number:

<button onclick="XtremePush.getInboxBadge()">Get Inbox Badge</button>