Send GCM Push Notifications using Azure Mobile Services

Azure Mobile Services is deprecated, please migrate to Azure App Service.

Tutorial requirements:

  1. First install Google Play Services package in the Android SDK Manager.

    NB: If using an Android Virtual Device then ensure your Target is set to Google APIs to allow Push Notifications to work.

  2. Create a new project in Google Developers Console.
    Turn on Google Cloud Messaging for Android. Create a new Public API access key. Create a new Server key.

  3. Copy the public API key Paste API key into Mobile Service’s Push > Google Cloud Messaging settings Save changes.

  4. Copy google-play-services.jar (from Android SDK libs) and notifications.jar (from Azure Mobiles Services SDK for Android) into the Android project’s libs folder.

  5. Add Push Notification permissions to the project’s AndroidManifest.xml.
    <permission android:name="**my_app_package**.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="**my_app_package**.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    

    NB: Replace all occurrences of **my_app_package** with the manifest’s package name attribute.

    Add the receiver block just before the application closing tag.
    eg. … </application>

    <receiver android:name="com.microsoft.windowsazure.notifications.NotificationsBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE"></action>
            <category android:name=" **my_app_package**"></category>
        </intent-filter>
    </receiver>
    

    NB: Replace **my_app_package** with the manifest’s package name attribute.
    NB: If you get a red text error on receiver _notifications.NotificationsBroadcastReceiver* then add dependencies to the build.gradle file and sync project libraries.

     dependencies {
         compile 'com.android.support:support-v4:+'
         compile 'com.google.code.gson:gson:2.2.2'
         compile fileTree(dir: 'libs', include: ['*.jar'])
     }
    

  6. Copy Google Project Number in overview section. Paste value into _ToDoActivity.java* as a String constant.

     public static final String PROJECT_ID = "**project-number**";
    

    In the _onCreate* method of ToDoActivity.java add a Notifications Manager handler.

     NotificationsManager.handleNotifications(this, PROJECT_ID, MyPushNotificationsHandler.class);
    

  7. Create a Channel class

     public class Channel {
         // Push Notifications - creates handle column in db table (dynamic schema)
         @com.google.gson.annotations.SerializedName("handle")
         private String mHandle;
    
         // Returns the handle
         public String getHandle() { return mHandle; }
    
         // Sets the handle
         public final void setHandle(String handle) { mHandle = handle; }
    
         // Item Id
         @com.google.gson.annotations.SerializedName("id")
         private String mId;
    
         //Returns the item id
         public String getId() { return mId; }
    
         //Sets the item id - @param id : id to set
         public final void setId(String id) { mId = id; }
     }
    

  8. Create MyPushNotificationsHandler class

     public class MyPushNotificationsHandler extends NotificationsHandler
     {
         @Override
         public void onRegistered(Context context, String gcmRegistrationId)
         {
             super.onRegistered(context, gcmRegistrationId);
    
             // + Support push notifications to users...
             MobileServiceClient client = ToDoActivity.getClient();
             MobileServiceTable&lt;Channel&gt; registrations = client.getTable(Channel.class);
    
             // Create a new Registration
             Channel channel = new Channel();
             channel.setHandle(gcmRegistrationId);
    
             // Insert the new Registration
             registrations.insert(channel, new TableOperationCallback&lt;Channel&gt;() {
    
                 public void onCompleted(Channel entity, Exception exception, ServiceFilterResponse response) {
    
                     if (exception != null) {
                         Log.e("PushHandler", exception.getMessage());
                     } else {
                         Log.i("PushHandler", "Registration OK");
                     }
                 }
             });
         }
     }
    

    Tip: To auto import classes in Android Studio enable _Add umabiguous imports on the fly*

  9. Create new Channel table in Azure Mobile Services.

  10. Edit TodoItem table Script > Insert

    function insert(item, user, request) {
        item.userId = user.userId;
        //request.execute();
    
        request.execute({
            success: function() {
                // Write to the response and then send the notification in the background
                request.respond();
                sendNotifications(item.text);
            }
        });
    
        // This insert script sends a push notification (with the text of the inserted item) to all channels stored in the Channel table.
        function sendNotifications(item_text) {
            var channelTable = tables.getTable('Channel');
            channelTable.read({
                success: function(channels) {
                    channels.forEach(function(channel) {
    
                        // Google Cloud Messaging
                        push.gcm.send(channel.handle, item_text, {
                            success: function(response) {
                                console.log('Push notification sent: ', response);
                            }, error: function(error) {
                                console.log('Error sending push notification: ', error);
                            }
                        });
    
                    });
                }
            });
        }
    }
    

    This will send a push notification upon successful insert of a Todo item.*

  11. Edit Channel table Script > Insert

    function insert(item, user, request) {
    //request.execute();
    
    // prevents duplicated channels
    var channelTable = tables.getTable('Channel');
        channelTable
            .where({ handle: item.handle })
            .read({ success: insertRegistrationIfNotFound });
        function insertRegistrationIfNotFound(existingRegistrations) {
            if (existingRegistrations.length > 0) {
                request.respond(200, existingRegistrations[0]);
            } else {
                request.execute();
            }
        }
    }
    

    This will prevent duplicate registrations of user and device handles.

  12. In the app add a Todo item to trigger a Push Notification

    The Push Notification will appear with the Todo item text.

    That’s all there is to it! If you wanted to take it to the next level you could use this backend Mobile Service and roll it out across other platforms like Windows Store, Windows Phone, iOS, or use cross platform tools like Xamerin or Phonegap.

For latest platform support, how to connect to other identities and push notification services check out the Azure online docs.