Sending Android push notifications from Mixpanel

Introduction

This guide will show you how to configure an Android app to send and receive push notifications. You should first read the Android API reference, and set up your application to update People Analytics records. In particular, you should be comfortable getting access to the MixpanelAPI object using your Mixpanel API key and calling MixpanelAPI.People.identify with a distinct id to identify your users to Mixpanel.

Enabling Google Cloud Messaging in your Google API Console

To enable Google Cloud Messaging (GCM) for Android, there are a few preliminary steps that must be taken. You will first need to turn on the Google Cloud Messaging Services from Google's API Console page. If you do you not have a Google API project yet, the following pop up will appear prompting you to create a project.

Click on the "Create Project..." to create a new project. Once you have created a new project (or if you already have an existing project), you will be taken to the console's dashboard. Take note of the browser URL. It should resemble https://code.google.com/apis/console/#project:XXXXXXXXXXXX. The XXXXXXXXXXXX will be your twelve digit Google Sender ID, which you will need to use in your code to register your application for push notifications.

From the Google API Console page, select "Services" from the left-hand navigation. Find "Google Cloud Messaging for Android" in the list of services, and turn it on by clicking the switch in the "Status" column.

Create an Google API key. From the Google API Console page, select "API Access" from the left navigation and click "Create new Server key...". You should see the following pop up.

Click the create button. The next page will contain a "Simple API Access" header, and below the header a "Key for server apps" box. Your Google API key will appear in this box, after the heading "API Key:".

Uploading your Google API key to Mixpanel

In order for Mixpanel to send Google Cloud Messaging notifications on your behalf, you will need to enter the Google API key generated from the last step into Mixpanel. To upload it, log in to your Mixpanel project and click the settings button (with the gear icon) on the lower left-hand corner of the screen.

In the settings pop-up, click on the "Notifications" tab. Then click on the word "Change" on the "Android GCM API Key" line, and paste in your Google API key into the text field that appears. Click the "Save changes" button underneath the text field to confirm.

Setting up your AndroidManifest.xml

You will need to edit your Android application's AndroidManifest.xml to allow all of the permissions necessary for your application to register, receive and react to Google Cloud Messaging notifications, and to install a listener for push notification messages from Google's servers.

To set up your permissions, Replace "YOUR_PACKAGE_NAME" with your own app's package name in the the following snippet of xml, and add them to your AndroidManifest.xml before the <application> tag:

<permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="YOUR_PACKAGE_NAME.permission.C2D_MESSAGE" />

You will also need the following permissions tags in your AndroidManifest.xml file. These tags can be pasted into the file directly below the C2D_MESSAGE tags, but you should leave their values as-is.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

Now you'll need to inform the OS to allow a service to run that will handle inbound notifications. Replace "YOUR_PACKAGE_NAME"with your own app's package name in the the following snippet of xml, and add them to your AndroidManifest.xml inside of your <application> tag:

<receiver android:name="com.mixpanel.android.mpmetrics.GCMReceiver"
          android:permission="com.google.android.c2dm.permission.SEND" >
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="YOUR_PACKAGE_NAME" />
    </intent-filter>
</receiver>

Be sure to change the YOUR_PACKAGE_NAME to the name of your application package when you paste these tags into your manifest!. If you don't use your own package name, your Google Cloud Messaging notifications won't work.

Android devices with an SDK version less than 8 cannot receive Google Cloud Messaging notifications. If notifications are necessity for your app's functionality, add the attribute android:minSdkVersion="8" to the <uses-sdk> tag in your AndroidManifest.xml file.

Setting up your app to receive notifications

Next, you'll need to tell Mixpanel which user record in People Analytics should receive the messages when they are sent from the Mixpanel app. To do this, add a call to People.initPushHandling right after you identify the user with people analytics. initPushHandling takes a single argument, your twelve digit Google Sender ID, represented as a string. This is the ID from your Google API console URL, mentioned above in Enabling Google Cloud Messaging

You must call identify before calling initPushHandling, or it won't be able to register your user. We recommend you call identify as early as you can, in your application's onCreate method if possible, so you might have code that looks like this:

protected void onCreate(Bundle savedInstanceState) {
    mMixpanel = MixpanelAPI.getInstance(this, YOUR_MIXPANEL_PROJECT_ID_TOKEN);
    MixpanelAPI.People people = mMixpanel.getPeople();
    people.identify(THE_DISTINCT_ID_FOR_THE_USER);
    people.initPushHandling(YOUR_12_DIGIT_GOOGLE_SENDER_ID);
}

Send a push notification

Once you have set up your permissions and set up GCMReciever as a receiver of Google Cloud Messaging notifications in your AndroidManifest.xml file and added a call to people.initPushHandling to your code, you're ready to send a notification!

Install and run your application on an Android device (not the emulator, it can't receive notifications.) Make sure to run the app until the calls to People.identify and People.initPushHandling have been run. For apps built according to our recommendations, these calls are in the onCreate method of your main application activity, so it is enough to simply open the app.

Press the back button to shut down your app. You should already be calling MixpanelAPI.flush in the onDestroy method of your main application activity, so closing it should send all waiting messages to Mixpanel.

Now log in to your Mixpanel project and select "Explore" from the left-hand navigation. There should be a user in the list with an "Android Devices" property. Select the user and click "Push Notification".

Compose your message, schedule it to send immediately, and click "Send this message".

The message should show up on your device.

Learning more

Mixpanel has a short sample Android application on github that includes support for push notifications and demonstrates some of our recommended practices.

We also recommend you take a look at the complete Mixpanel Android API reference, which provides detailed information for all objects and methods available in the Mixpanel library.

Advanced features

The information above should allow you to enable and use Mixpanel push notifications for many applications, but if you want to handle registration and message handling manually, or if you are using multiple Mixpanel projects within the same application, there are some other things you should know.

Using the low level notifications API

Using GCMReciever and initPushHandling is a simple and straightforward way to get Mixpanel push notifications into your app, but if your application is already configured and handling Google Cloud Messaging you can use lower level methods to work with Mixpanel's notification features. You shouldn't intermix these techniques with calls to initPushHandling.

You can send a registration id directly to Mixpanel using People.setPushRegistrationId. You should call setPushRegistrationId with the push registration identifier string as passed to your application's GCMIntentService.onRegistered method (This is NOT the same argument you should provide to initPushHandling). Similarly, you can unregister a Google Cloud Messaging identifier with People.clearPushRegistrationId. Both of these methods should be called after you've called People.identify, or Mixpanel won't know which user to register or unregister.

A service you set up to handle registration might look like this:

public class YourIntentService extends GCMBaseIntentService {
    private MixpanelAPI mMixpanel;
    public YourIntentService() {
        mMixpanel = MixpanelAPI.getInstance(this, "YOUR_MIXPANEL_PROJECT_TOKEN");
    }

    protected void onRegistered(Context context, String registrationId) {
        MixpanelAPI.People people = mMixpanel.getPeople();
        people.identify("USER_DISTINCT_ID");
        people.setPushRegistrationId(registrationId);
    }

    protected void onUnregistered(Context context, String registrationId) {
        MixpanelAPI.People people = mMixpanel.getPeople();
        people.identify("USER_DISTINCT_ID");
        people.clearPushRegistrationId();
    }
}

Incoming messages from Mixpanel will contain the key "mp_message", associated with the text of the message from Mixpanel as a string. You can handle or ignore the messages in your receivers with code like the following:

public void onReceive(Context context, Intent intent) {
    if (intent.getExtras().containsKey("mp_message")) {
        String mp_message = intent.getExtras().getString("mp_message");
        //mp_message now contains the notification's text
    }
}

If you are handling registration and receiving notifications yourself, you shouldn't include the GCMReciever <receiver> tag in your AndroidManifest.xml file.

initPushHandling and multiple projects

If you are allowing Mixpanel to handle registering and unregistering users for you, whenever you call initPushHandling, all instances of MixpanelAPI you have created that have an identified user will take the register into account. For example:

mMixpanel = MixpanelAPI.getInstance(this, "YOUR_MIXPANEL_PROJECT_TOKEN");
mMixpanel.getPeople().identify("some distinct_id_1");

mMixpanel2 = MixpanelAPI.getInstance(this, "YOUR_OTHER_MIXPANEL_PROJECT_TOKEN");
mMixpanel2.getPeople().identify("some distinct_id_2");

mMixpanel2.initPushHandling("123456789123");
//both users distinct_id_1 and distinct_id_2 in their respective projects
//will be treated as having enabled push.
Document Sections