Overview

Skill Level: Intermediate

Developers working with Android apps and Firebase Cloud Messaging (FCM) can follow the steps in this tutorial to implement mobile app messaging in their apps. The instructions describe how you can use the SDK’s Firebase message service or an external Firebase message service.

WARNING: When IBM Mobile App Messaging stores data that you send, the data is not encrypted. IBM Mobile App Messaging recommends that you do not transmit sensitive information in inbox, inapp, and mobile app messages. We do not encrypt the data in our databases or log files, or when stored on the device. If you must transmit sensitive information, encrypt the data before sending it and decrypt the data in memory on the device.

Prerequisites

To get started, you need:

  • An account with Acoustic Campaign.

TIP: If you do not already have a Acoustic Campaign account, contact your Client Services representative or sales.

Are you using Google Cloud Messaging (GCM)?

Are you implementing a new project?
IBM recommends that you use FCM because Google has deprecated GCM and will soon disable it entirely. 

Do you have an existing project that uses GCM?
IBM recommends that you migrate from GCM to FCM. For information, see Migrating from Google Cloud Messaging (GCM) to Firebase Cloud Messaging (FCM) to get your code running under FCM. 

Step-by-step

  1. Create a Google API project with Firebase Cloud Messaging.

    1. In your app’s project in Android Studio, go to the Tools menu and open Firebase. A Firebase Assistant pane opens.
    2. Select Cloud Messaging and then click Set up Firebase Cloud Messaging.
    3. If you are using the application with FCM for the first time, click on Connect to Firebase and follow the instructions. Otherwise, skip to step 4.
    4. Click Add FCM to your app.
    5. Go to the Firebase Cloud Messaging console and click your app. You must be logged into your Google account. If you can’t find your app, click Add FCM to your app, as described in step 4, and then return to this page.
    6. Click the app’s options link and then select Settings.
    7. Use only the gms dependencies that are required for the SDK and the app, which include:
      • com.google.android.gms:play-services-base:<google play services version>
      • com.google.android.gms:play-services-location:<google play services version>
      • com.google.android.gms:play-services-maps:<google play services version>
      • com.google.android.firebase:firebase-messaging:<google play services version>
    8. Ensure that your gms dependencies and the fcm dependencies use the same version. For example, the following gms and fcm dependencies use 11.8.0. 
      • com.google.android.gms:play-services-base: 11.8.0
      • com.google.android.gms:play-services-location: 11.8.0
      • com.google.android.gms:play-services-maps: 11.8.0
      • com.google.firebase:firebase-messaging: 11.8.0
    9. Set messagingService to fcm in the MceConfig.json file.
       "senderId":"",
       "messagingService": "fcm",
      

    10. Optional. If you are using an external Firebase messaging service instead of the SDK’s Firebase messaging service, you can use com.ibm.mce.sdk.api.fcm.FcmApi. This API provides two methods that let you pass fcm messages to the sdk:

      • public static boolean isFcmMessage(RemoteMessage remoteMessage)
         Checks if a remote message is a MCE remote message 
        
      • public static void handleMceFcmMessage(Context context, RemoteMessage remoteMessage) 
        Handles a MCE fcm message in the sdk 

      For example, add the following to the sample app:

      package com.ibm.mce.samples.gcm;
      
      import com.google.firebase.messaging.FirebaseMessagingService;
      import com.google.firebase.messaging.RemoteMessage;
      import com.ibm.mce.sdk.api.fcm.FcmApi;
      
      public class SampleFirebaseMessagingService extends FirebaseMessagingService {
      
          @Override
          public void onMessageReceived(RemoteMessage remoteMessage) {
              if(FcmApi.isFcmMessage(remoteMessage)) {
                  FcmApi.handleMceFcmMessage(getApplicationContext(), remoteMessage);
              }
          }
      }
      
  2. Register your Android application in Watson Campaign Automation.

    You must register your Android app with Acoustic Campaign.

    For more information about adding your app in Acoustic Campaign, see Add an app in Acoustic Campaign.

    Restriction: Acoustic Campaign documentation contains information for marketers, app developers, and organization administrators and requires a user name and password. If you need a user name and password, contact your Client Services representative.

  3. Implement the SDK.

    After you register your Android app, you must implement it so that you can start testing and creating notifications.

    TIP: It is not recommended to allow your app to be installed on external storage cards for several reasons that Google states on the developer site at http://developer.android.com/guide/topics/data/install-location.html#Should. Your app should instead be installed on internal memory.

    1. Download the Android SDK as described in the Prerequisites.
    2. Add the Android SDK to your Gradle project by copying the Android SDK JAR file to your libs folder. If you do not have a libs folder, create one next to your src folder. Next, in your build.properties file, make sure that you have the following code in the dependencies section, where <play-services version> is the latest version of the play-services package.
      dependencies {
       implementation fileTree(dir: 'libs', include: ['*.jar'])
       implementation fileTree(dir: 'libs', include: ['*.aar'])
       implementation 'com.google.android.gms:play-services-base:<play-services version>'
       implementation 'com.google.firebase:firebase-messaging:<play-services version>'
      

      If you use location:

      implementation 'com.google.android.gms:play-services-location:<play-services version>'
      
    3. Optional: If you do not have a Gradle project, follow these steps. 
      A. Create a folder in your project that is called libs, and move the SDK JAR file to it. You can find the SDK JAR file in the root directory after you extract the SDK package.
      B. Select your project.
      C. Right-click properties.
      D. Choose java build path.
      E. Select libraries tab.
      F. Choose Add JARs, and browse to Android SDK JAR file in the libs folder.
    4. Modify the AndroidManifest.xml.  Follow these steps.
      1. Set the minimum Android SDK version to 19 (Android 4.4) or higher in your application’s build.gradle file or AndroidManifest.xml file. For simple push, you can set Android SDK version to 16 or higher. The 3.x Android SDK is not supported with previous versions of Android. The target version should be the latest release version of Android.

        Note: For Android SDK versions 16, 17, and 18, ensure that location services are disabled.

      2. The following permissions are needed for the SDK to work properly. These are positioned as the child of the <manifest> node. Replace the two occurrences of YOUR_APP_PACKAGE_NAME with your application package name.

        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.WAKE_LOCK" />
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
        
      3. If you want to use the dial action in the notification details page, add the following information as a child of the <manifest> node:
        <uses-permission android:name="android.permission.CALL_PHONE" /> 
        

        If you plan to publish your app in the Google Play store and want to allow non-phone devices to download your app, also include:

        <uses-feature android:name="android.hardware.telephony" android:required="false" /> 
      4. Add the following XML to the <application> node. Replace the occurrence of YOUR_APP_PACKAGE_NAME with your application package name.

        Add this XML:

        <provider
         android:name="com.ibm.mce.sdk.db.Provider"
         android:authorities="YOUR_APP_PACKAGE_NAME.MCE_PROVIDER"
         android:exported="false" />
        
        <receiver android:name="com.ibm.mce.sdk.notification.NotifActionReceiver" />
        <receiver android:name="com.ibm.mce.sdk.wi.AlarmReceiver" >
          <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
          </intent-filter>
          <intent-filter>
            <action android:name="android.intent.action.TIMEZONE_CHANGED" />
          </intent-filter>
          <intent-filter>
            <action android:name="android.intent.action.LOCALE_CHANGED" />
          </intent-filter>
          <intent-filter>
            <action android:name="android.intent.action.PACKAGE_REPLACED" />
            <data android:scheme="package" />
          </intent-filter>
        </receiver>
        <service android:name="com.ibm.mce.sdk.events.EventsAlarmListener" />
        <service android:name="com.ibm.mce.sdk.attributes.AttributesQueueConsumer" />
        <service android:name="com.ibm.mce.sdk.registration.RegistrationIntentService" />
        <service android:name="com.ibm.mce.sdk.registration.PhoneHomeIntentService" />
        <service android:name="com.ibm.mce.sdk.job.MceJobService" android:permission="android.permission.BIND_JOB_SERVICE"/>
        
      5. Add the following XML to the <application> node for FCM support:

        <!-- FCM Registration -->
        <service
          android:name="com.ibm.mce.sdk.fcm.FcmInstanceIdService">
          <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
          </intent-filter>
        </service>
        <!-- FCM Messages -->
        <service
          android:name="com.ibm.mce.sdk.fcm.FcmMessagingService">
          <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
          </intent-filter>
        </service>
        

        Note: If you are using an external Firebase messaging service, replace <service android:name="com.ibm.mce.sdk.fcm.FcmMessagingService" /> with <service android:name=<YOUR_SERVICE_CLASS_NAME> />

      6. Add the session tracking service if you want sessions to be timeout automatically, even if the application is in the background. This service is scheduled to check whether the current session timed out <session duration> + 1 minute after the application was sent to the background.

        <service android:name="com.ibm.mce.sdk.session.SessionTrackingIntentService"/>
      7. Set your application class to a class that extends com.ibm.mce.sdk.api.MceApplication. Replace YOUR_APP_PACKAGE_NAME with your package name.

        You can use the following as a template for your application class:

        package YOUR_APP_PACKAGE_NAME;
        import android.annotation.TargetApi;
        import android.app.NotificationChannel;
        import android.app.NotificationManager;
        import android.content.Context;
        import android.os.Build;
        import com.ibm.mce.sdk.api.MceApplication;
        import com.ibm.mce.sdk.api.MceSdk;
        import com.ibm.mce.sdk.api.notification.NotificationsPreference;
        public class MyApplication extends MceApplication {
        public void onCreate() {
        super.onCreate();
        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) {
        createNotificationChannel(getApplicationContext());
        }
        }@
        TargetApi(26) private static void createNotificationChannel(Context context) {
        String MY_SAMPLE_NOTIFICATION_CHANNEL_ID = context.getString(R.string.notif_channel_id);
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel channel = notificationManager.getNotificationChannel(MY_SAMPLE_NOTIFICATION_CHANNEL_ID);
        if (channel == null) {
        CharSequence name = context.getString(R.string.notif_channel_name);
        String description = context.getString(R.string.notif_channel_description);
        int importance = NotificationManager.IMPORTANCE_HIGH;
        channel = new NotificationChannel(MY_SAMPLE_NOTIFICATION_CHANNEL_ID, name, importance);
        channel.setDescription(description);
        NotificationsPreference notificationsPreference = MceSdk.getNotificationsClient().getNotificationsPreference();
        notificationsPreference.setNotificationChannelId(context, MY_SAMPLE_NOTIFICATION_CHANNEL_ID);
        notificationManager.createNotificationChannel(channel);
        }
        }
        }

        The class above refers to the following that you will need to add to strings.xml:

        <string name="notif_channel_id">my-notification-channel</string> <string name="notif_channel_name">My sample notification channel</string> <string name="notif_channel_description">My sample notification channel description</string>

        If you are targeting Android O or higher, you will have to set a default notification channel as well. Add this to your <application> node in AndroidManifest.xml:

        <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/notif_channel_id" /
      8. If you implemented an MceBroadcastReceiver, be sure to add it to AndroidManifest.xml under the <application> node:
        <receiver android:name=".MyMceBroadcastReceiver">
        <intent-filter>
        <action android:name="com.ibm.mce.sdk.NOTIFIER" />
        </intent-filter>
        </receiver>
      9. Configure your Android app not to back up inappropriate SDK files. See Automated Restores on Android.
    5. You have two options for setting properties: using the MceConfig.json properties file or the MceSdkConfiguration object. The most common way is by copying MceConfig.json from one of the sample apps in the SDK into your app/src/main/assets directory. We also provide a way to configure via API.
      • MceConfig.json properties file
        To set MCE properties with the MceConfig.json, copy the MceConfig.json from a sample app to the project’s assets . Create the assets directory under app/main/src if it doesn’t exist.

        The baseUrl, appKey, senderId, and messagingService are required. All other values are optional.

        baseURL – Replace the server URL with your production URL. Typically this will be something like “https://sdk1.ibm.xtify.com/3.0” if you are on pod 1.To confirm the baseURL for your pod, see Setting the baseURL.

        appKey – Replace “YOUR APP KEY” with the app key generated from Watson Campaign Automation. Do not change the app key after you publish your app.

        senderId – The value for senderId is empty when using FCM.

        messagingService – Be sure to choose “fcm” and not “gcm.”

         

        Note: For information about other properties in the MceConfig.json, see these topics:

         

        MceConfig.json example

        "Note: If you are in Europe, you may need to change the value in 'baseUrl' below to": "https://sdk6.ibm.xtify.com",
         "baseUrl": "https://sdk.ibm.xtify.com/3.0",
        
         "appKey": {
         "prod":"YOUR APP KEY"
         },
         "Set this to the google project number if you are using GCM or to an empty string if you are using FCM": "",
         "senderId": "",
        
         "Use 'gcm' for GCM of 'fcm' for FCM": "",
         "messagingService": "fcm",
        
         "Will invalidate the existing user/channel ID if they exist when set to true": "This is for testing only. Do not ship with this set to true unless you understand what you are doing",
         "invalidateExistingUser": false,
        
         "Setting sessionEnabled to true will trigger session start and session end events": "",
         "sessionsEnabled": true,
        
         "sessionTimeout is the number of minutes the SDK wait while the application is in the background before sending session end event": "",
         "sessionTimeout": 20,
        
         "metricTimeInterval defines the interval in minutes between SDK events sync with the server. This is only for events that are sent to the event queue": "",
         "metricTimeInterval": 3,
        
         "Set groupNotificationsByAttribution to true to bundle together notifications with the same attribution": "This will work on Android N and above",
         "groupNotificationsByAttribution": false,
        
         "Choose one of the following values for loglevel: ": ["none", "error", "warn", "info", "debug", "verbose"],
         "loglevel": "error",
        
         "Please note, the log iteration files will be stored under": "<application cache folder on sdcard>/ibm-mce-android-sdk/logs/<installation time folder, format: yyyy-MM-dd-HH-mm-ss>",
         "logfile": false,
        
         "The number of log iteration files": "After reaching this number, the log files will be overwritten in order",
         "logIterations": 1,
        
         "The number of hours each log iteration will hold": "0 is for infinite time",
         "logIterationDurationInHours": 0,
        
         "The number of log lines that will be stored in the ram before writing to the log file": "The higher this number is, more log lines will be lost in case of a crash.",
         "logBufferSize": 10,
        
         "Set useInMemoryImageCache to true to use RAM cache for inbox images": "",
         "useInMemoryImageCache": true,
        
         "Set useFileImageCache to true to use file based cache for inbox images": "Uses the sdcard application cache folder",
         "useFileImageCache": true,
        
         "The size of the inbox images RAM cache in MB": "",
         "inMemoryImageCacheCapacityInMB": 20,
        
         "The size of the inbox images file based cache in MB": "",
         "fileImageCacheCapacityInMB": 100,
        
         "location is only required if location support is needed. Please note that unlike iOS, location support is not enabled automatically. Enabling location support is done in the application code (see documentation).": "",
         "location": {
         "The sync key is only used to customize the iBeacon and Geofence syncing service, it is not required for those features": "",
         "sync": {
         "Specify how long to wait before syncing again on significant location change in seconds, default 5 minutes":"",
         "syncInterval": 300,
        
         "Location Sync radius is in meters, default 100km":"",
         "syncRadius": 100000,
        
         "Specify how long to wait before retrieving a new location from the device, default 5 minutes":"",
         "locationResponsiveness": 300,
        
         "Specify the minimum results when looking for locations nearby, default is 1, minimum value is 1":"",
         "minLocationsForSearch": 1,
        
         "Specify the maximum results when looking for locations nearby, default is 1, minimum value is 1":"",
         "maxLocationsForSearch": 20,
        
         "Specify the location providers that will be used to retrieve the device location. 'gps' - gps location. 'network' - wifi + cellular, default is gps + network":"",
         "providerPreferences": ["gps", "network"] },
        
         "Please note, unlike iOS, the existence of the ibeacon key does not enable iBeacon support, iBeacon support is enabled only if iBeacons are nearby":"",
         "ibeacon": {
        
         "Please note: if this is not set, iBeacon events will not be sent": "This value should never be empty. Leave the default value if you don't want to use iBeacons",
         "uuid": "YOUR-IBEACONS-UUID",
        
         "Specify how much time the sdk will scan for iBeacons in every scan session while the application is in the foreground, default is 5 seconds": "",
         "beaconForegroundScanDuration": 5,
        
         "Specify how much time the sdk will wait between iBeacons scan sessions while the application is in the foreground, default is 30 seconds": "",
         "beaconForegroundScanInterval": 30,
        
         "Specify how much time the sdk will scan for iBeacons in every scan session while the application is in the background, default is 30 seconds": "",
         "beaconBackgroundScanDuration": 30,
        
         "Specify how much time the sdk will wait between iBeacons scan sessions while the application is in the background, default is 5 minutes": "",
         "beaconBackgroundScanInterval": 300
         }
         }
        }
        
      • MceSdkConfiguration object
        To set the sdk configuration in the application code by using the MceSdkConfiguration object, ensure that the application class is not an MceApplication and that you call the MceApplication init method with an MceSdkConfiguration object. If you do not set a config property, the default value is used.
        For example,
        import com.ibm.mce.sdk.api.MceApplication;
        import com.ibm.mce.sdk.api.MceSdkConfiguration;
        import com.ibm.mce.sdk.api.SdkInitLifecycleCallbacks;
        
        import org.json.JSONArray;
        import org.json.JSONException;
        import org.json.JSONObject;
        
        public class SampleApplication extends Application {
        
         @Override
         public void onCreate() {
         super.onCreate();
         String appKey = "<YOUR APP KEY>";
         String senderId = "<YOUR SENDER ID>";
         MceSdkConfiguration mceSdkConfiguration = new MceSdkConfiguration(appKey, senderId);
        
         mceSdkConfiguration.setBaseUrl("<YOUR BASE URL>");
        
         mceSdkConfiguration.setMessagingService(MceSdkConfiguration.MessagingService.fcm);
         mceSdkConfiguration.setGroupNotificationsByAttribution(true);
        
         mceSdkConfiguration.setLogBufferSize(10);
         mceSdkConfiguration.setLogFile(true);
         mceSdkConfiguration.setLogIterationDurationInHours(1);
         mceSdkConfiguration.setLogLevel(Logger.LogLevel.error);
        
         mceSdkConfiguration.setMetricTimeInterval(300);
        
         mceSdkConfiguration.setSessionsEnabled(true);
         mceSdkConfiguration.setSessionTimeout(20);
         mceSdkConfiguration.setUseFileImageCache(true);
         mceSdkConfiguration.setUseInMemoryImageCache(true);
         mceSdkConfiguration.setFileImageCacheCapacityInMB(200);
         mceSdkConfiguration.setInMemoryImageCacheCapacityInMB(20);
         
         
         MceSdkConfiguration.LocationConfiguration.SyncConfiguration syncConfiguration = mceSdkConfiguration.getLocationConfiguration().getSyncConfiguration();
         try {
         syncConfiguration.setProviderPreferences(new JSONArray("[\"gps\", \"network\"]"));
         } catch (JSONException e) {
         }
         syncConfiguration.setLocationResponsiveness(300);
         syncConfiguration.setSyncInterval(300);
         syncConfiguration.setSyncRadius(100000);
         syncConfiguration.setMinLocationsForSearch(1);
         syncConfiguration.setMaxLocationsForSearch(20);
        
         MceSdkConfiguration.LocationConfiguration.IBeaconConfiguration iBeaconConfiguration = mceSdkConfiguration.getLocationConfiguration().getiBeaconConfiguration();
         iBeaconConfiguration.setUuid("<YOUR UUID>");
         iBeaconConfiguration.setBeaconForegroundScanDuration(5);
         iBeaconConfiguration.setBeaconForegroundScanInterval(30);
         iBeaconConfiguration.setBeaconBackgroundScanDuration(30);
         iBeaconConfiguration.setBeaconBackgroundScanInterval(300);
        
        
         MceApplication.init(this, mceSdkConfiguration, new SdkInitLifecycleCallbacks() {
         @Override
         public void handleMetadata(Bundle bundle) {
        
         }
        
         @Override
         public void onPluginActionLoad(JSONObject jsonObject) {
        
         }
        
         @Override
         public void onStart(MceSdkConfiguration mceSdkConfiguration) {
        
         }
         });
         }
        } 
        
    6. On new Android platforms, you will need to request some permissions explicitly. See Requesting location permissions on Android for details.
    7. Implement MceBroadcastReceiver if you want to monitor events in the Android SDK, such as SDK registration, FCM registration, and notification received. Create a new MceBroadcastReceiver implementation class. The following example shows how to create a new MceBroadcastReceiver implementation class with FCM:

      package YOUR_APP_PACKAGE;
      import android.content.Context;
      import java.util.Date;
      import android.content.Intent;
      import android.location.Location;
      import android.os.Bundle;
      import android.util.Log;
      import com.ibm.mce.sdk.api.MceBroadcastReceiver;
      import com.ibm.mce.sdk.api.attribute.AttributesOperation;
      import com.ibm.mce.sdk.api.event.Event;
      import com.ibm.mce.sdk.api.notification.NotificationDetails;
      import com.ibm.mce.sdk.location.MceLocation;
      import com.ibm.mce.sdk.api.broadcast.EventBroadcastUtil;
      import java.util.List;
      public class MyMceBroadcastReceiver extends MceBroadcastReceiver
      {
      @Override
      public void onSdkRegistered(Context context) {
      // Handle the SDK registration event
      // context - The application context
      }
      @Override
      public void onDeliveryChannelRegistered(Context context) {
      // Handle the FCM registration event
      // context - The application context
      }
      @Override
      public void onSdkRegistrationChanged(Context context) {
      // context - The application context
      }
      @Override
      public void onSdkRegistrationUpdated(Context context) {
      // context - The application context
      }
      @Override public void onMessage(Context context, NotificationDetails notificationDetails, Bundle extraPayload) {
      // Handle the notification received event
      // context - The application context
      // notificationDetails - The received notification
      // extraPayload- Additional payload that arrived with the notification
      }
      @Override
      public void onSessionStart(Context context, Date sessionStartDate) {
      // context - The application context
      // sessionStartDate- The new session start time
      }
      @Override
      public void onSessionEnd(Context context, Date sessionEndDate, long sessionDurationInMinutes) {
      // context - The application context
      // sessionEndDate- The session end time
      // sessionDurationInMinutes - The session duration in minutes
      }
      @Override
      public void onNotificationAction(Context context, Date actionTime, String pushType, String actionType, String actionValue) {
      // context - The application context
      // actionTime- The time the action was clicked on
      // pushType - always "simple"
      // actionType - The type of the action
      // actionValue - the value of the "value" key in the payload.
      }
      @Override
      public void onAttributesOperation(Context context, AttributesOperation attributesOperation) {
      // context - The application context
      // attributesOperation - The operation that was executed
      }
      @Override
      public void onEventsSend(Context context, List < Event > list) {
      // context - The application context
      // events- The events that were sent
      }
      @Override
      public void onIllegalNotification(Context context, Intent intent) {
      // context - The application context
      // intent- The intent that contains the illegal notification
      }
      @Override
      public void onNonMceBroadcast(Context context, Intent intent) {
      // context - The application context
      // intent- The intent that contains the non MCE broadcast
      }
      /**
      * This method is called when a location event occurs
      * @param location The related location
      * @param locationType The related location type
      * @param locationEventType The related location event type
      */
      public void onLocationEvent(Context context, MceLocation location, LocationType locationType, LocationEventType locationEventType) {
      // do something interesting with the location event
      };
      /**
      * This method is called when the device location is updated
      * @param context The application's context
      * @param location The device location
      */
      public void onLocationUpdate(Context context, Location location) {
      // do something interesting with the location update
      }
      @Override
      public void onReceive(Context context, Intent intent) {
      Log.i(getClass().getSimpleName(), "Received intent: " + intent.toString());
      if (intent == null || intent.getAction() == null) {
      return;
      }
      try {
      EventBroadcastUtil.handleBroadcast(context, intent, this);
      } catch (Throwable t) {
      Log.e(getClass().getSimpleName(), "Unexpected error on receive: ", t);
      }
      }
      @Override
      public void onC2dmError(Context context, String errorId) {
      Log.i(getClass().getSimpleName(), "C2DM errorId: " + errorId);
      }
      }
  4. Set up your emulator for testing.

    You can use the Android sample app in Android Studio to view and test the structure and features of the Android SDK. You use the sample app included in the SDK to teach you how to build a mobile app message and to show you the capabilities that are available. The sample app shows you the following information:

    • Credential and ID screens that display the following values: user ID, channel ID, development app key, and production app key.
    • A push action screen that displays the default and custom push actions that could be used when you send a mobile app message to your app users.
    • A custom action screen that displays details about the example categories you could use with the sample app.
    • Test events so you can send events to the server.
    • Test user attributes so you can send a user attribute to the server.

    You can test the Android SDK by using either Eclipse ADT or Gradle.

    1. Go to ibm-mobile-push-android-sdk-<version number>/samples/Demo. Make sure Demo is selected.
    2. Select the 1:Project tab.
    3. Set up your MceConfig.json to use your baseUrl, appKey, senderId and messagingService.
    4. If you’re not using the US server, go to app/assets/MceConfig.json and update your ‘baseUrl’ to your server’s URL. For example, eu is for European Union and a URL is for a different MCE server.
    5. When you create your Android Virtual Device (AVD), build a virtual device that is based on the Google Messaging API. A normal AVD results in silent failure.
      1. In Android Studio, select Tools > Android > SDK Manager, and make sure the “Google APIs” item is installed under the versions you are supporting.
      2. In Android Studio, select Tools > Android > AVD Manager.
        1. Select New, and enter a name.
        2. Under Target, make sure to select an option that uses Google APIs, such as Google APIs (Google Inc.) – API Level 16.
        3. After the device is created and started, you must also add an active Google account to the device through Settings > Accounts.
    6. Plug in an Android device into your machine, and run the app.
    7. Your emulator must be connected to a Google account for the FCM push to work. You can verify that the connection is initially working by sending an email to an account that was set up on your emulator.
  5. To enable multiple FCM providers

    1. Add a class to support FCM messages: Example create
    class MyFirebaseMessagingService extends FirebaseMessagingService.

    Add import com.ibm.mce.sdk.api.fcm.FcmApi;

    Add the following code:

    If (FcmApi.isFcmMessage(remoteMessage)) {
        FcmApi.handleMceFcmMessage(getApplicationContext(), remoteMessage);
        return;
    }
    

    To public void onMessageReceived(RemoteMessage remoteMessage) method.

    2. Replace FcmMessagingService in your manifest with your FCM message handler class. In this example it’s: MyFirebaseMessagingService.

    <!-- FCM Messages -->
       <service
           android:name=".MyFirebaseMessagingService">
    <!-- Rreplace android:name="com.ibm.mce.sdk.fcm.FcmMessagingService" With
      android:name=".MyFirebaseMessagingService"
    -->
           <intent-filter>
               <action android:name="com.google.firebase.MESSAGING_EVENT"/>
           </intent-filter>
       </service>
    

    When fcm notification arrives, os calls MyFirebaseMessagingService::onMessageReceived(). The code checks if the message is from WCA.

    A message from WCA has “alert”: in the sub-document message payload.
    If the payload came from WCA, the SDK handles the message and returns. Otherwise, the message is handled by MyFirebaseMessagingService.

Expected outcome

This tutorial takes you through the basic steps to configure mobile app messages in Android apps that use Firebase Cloud Messaging (FCM). For more information, see the Documentation.

Go Back to Mobile Application Messaging home page.

5 comments on"Getting Started with Mobile App Messaging in Android Apps"

  1. Changed some thing in the tutorial for example in the tutorial are using this clase

    but in the SDK 3.7.1.0.3 are using this :

    when i send a notification whit firebase work fine, but when i try do the same in Watson dont recive nothing
    do you have idea of what are happening

  2. Adrian Hill June 18, 2018

    Android Oreo forbids declaration of broadcast receivers, however your configuration steps show ‘GcmBroadcastReceiver’. How can the sdk be used with Android Oreo?

  3. Adrian Hill June 19, 2018

    Android Oreo forbids declaring broadcast receivers. i.e. is not permitted.

    What is the solution to this issue please?

  4. Cristhopper Armenta October 23, 2018

    FcmMessagingService is deprecated in favor to FirebaseMessagingService. Can you please update your guide with this?

Join The Discussion

Your email address will not be published. Required fields are marked *