You are on page 1of 14

Sending Push Notifications from Azure Mobile

Apps

Overview
A push notification is used to deliver information, such as a message, from a backend system to an
application on a mobile device in order to increase application engagement and usage. The notification can
be sent at anytime, even when the user is not actively using the targeted application.

Backend systems send push notifications to mobile devices through Platform Notification Systems (PNS),
as shown in the following diagram:

To send a push notification, the backend system contacts the platform-specific PNS to send a notification
to a client application instance. This significantly increases the complexity of the backend when cross-
platform push notifications are required, because the backend must use each platform-specific PNS API
and protocol.

Azure Notification Hubs eliminate this complexity by abstracting the details of the different platform
notification systems, allowing a cross-platform notification to be sent with a single API call, as shown in the
following diagram:

To send a push notification, the backend system only contacts the Azure Notification Hub, which in turn
communicates with the different platform notification systems, therefore decreasing the complexity of the
backend code that sends push notifications.

Azure Mobile Apps have built-in support for push notifications using notification hubs. The process for
sending a push notification from an Azure Mobile Apps instance to a Xamarin.Forms application is as
follows:

1. The Xamarin.Forms application registers with the PNS, which returns a handle.
2. The Azure Mobile Apps instance sends a notification to its Azure Notification Hub, specifying the
handle of the device to be targeted.
3. The Azure Notification Hub sends the notification to the appropriate PNS for the device.
4. The PNS sends the notification to the specified device.
5. The Xamarin.Forms application processes the notification and displays it.

The sample application demonstrates a todo list application whose data is stored in an Azure Mobile Apps
instance. Every time a new item is added to the Azure Mobile Apps instance, a push notification is sent to
the Xamarin.Forms application. The following screenshots show each platform displaying the received
push notification:
For more information about Azure Notification Hubs, see Azure Notification Hubs and Add push
notifications to your Xamarin.Forms app on the Azure Documentation Center.

Azure and Platform Notification System Setup


The process for integrating an Azure Notification Hub into an Azure Mobile Apps instance is as follows:

1. Create an Azure Mobile Apps instance. For more information, see Consuming an Azure Mobile App.
2. Create a notification hub. For more information, see Create a Notification Hub on the Azure
Documentation Center.
3. Update the Azure Mobile Apps instance to send push notifications. For more information, see Update
the server project to send push notifications on the Azure Documentation Center.
4. Register with each PNS.
5. Configure the notification hub to communicate with each PNS.

The following sections provide additional setup instructions for each platform.

iOS

The following additional steps must be carried out to use Apple Push Notification Service (APNS) from an
Azure Notification Hub:

1. Generate a certificate signing request for the push certificate with the Keychain Access tool. For
more information, see Generate the Certificate Signing Request file for the push certificate on the
Azure Documentation Center.
2. Register the Xamarin.Forms application for push notification support on the Apple Developer Center.
For more information, see Register your app for push notifications on the Azure Documentation
Center.
3. Create a push notifications enabled provisioning profile for the Xamarin.Forms application on the
Apple Developer Center. For more information, see Create a provisioning profile for the app on the
Azure Documentation Center.
4. Configure the notification hub to communicate with APNS. For more information, see Configure the
notification hub for APNS.
5. Configure the Xamarin.Forms application to use the new App ID and provisioning profile. For more
information, see Configuring the iOS project in Xamarin Studio or Configuring the iOS project in
Visual Studio on the Azure Documentation Center.

Android

The following additional steps must be carried out to use Firebase Cloud Messaging (FCM) from an Azure
Notification Hub:

1. Register for FCM. For more information, see Enable Google Cloud Messaging on the Azure
Documentation Center.
2. Configure the notification hub to communicate with FCM. For more information, see Configure the
Mobile App backend to send push requests using GCM on the Azure Documentation Center.

Universal Windows Platform

The following additional steps must be carried out to use the Windows Notification Service (WNS) from an
Azure Notification Hub:

1. Register for the Windows Notification Service (WNS). For more information, see Register your
Windows app for push notifications with WNS on the Azure Documentation Center.
2. Configure the notification hub to communicate with WNS. For more information, see Configure the
notification hub for WNS on the Azure Documentation Center.

Adding Push Notification Support to the


Xamarin.Forms Application
The following sections discuss the implementation required in each platform-specific project to support
push notifications.
iOS

The process for implementing push notification support in an iOS application is as follows:

1. Register with the Apple Push Notification Service (APNS) in the


AppDelegate.FinishedLaunching method. For more information, see Registering with the
Apple Push Notification System.
2. Implement the AppDelegate.RegisteredForRemoteNotifications method to handle the
registration response. For more information, see Handling the Registration Response.
3. Implement the AppDelegate.DidReceiveRemoteNotification method to process incoming
push notifications. For more information, see Processing Incoming Push Notifications.

Registering with the Apple Push Notification Service

Before an iOS application can receive push notifications, it must register with the Apple Push Notification
Service (APNS), which will generate a unique device token and return it to the application. Registration is
invoked in the FinishedLaunching override in the AppDelegate class:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)


{
...
var settings = UIUserNotificationSettings.GetSettingsForTypes(
UIUserNotificationType.Alert, new NSSet());

UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
...
}

When an iOS application registers with APNS it must specify the types of push notifications it would like to
receive. The RegisterUserNotificationSettings method registers the types of notifications the
application can receive, with the RegisterForRemoteNotifications method registering to receive
push notifications from APNS.

Failing to call the RegisterUserNotificationSettings method will result in push notifications being
silently received by the application.

Handling the Registration Response


The APNS registration request occurs in the background. When the response is received, iOS will call the
RegisteredForRemoteNotifications override in the AppDelegate class:

public override void RegisteredForRemoteNotifications(UIApplication


application, NSData deviceToken)
{
const string templateBodyAPNS = "{\"aps\":
{\"alert\":\"$(messageParam)\"}}";

JObject templates = new JObject();


templates["genericMessage"] = new JObject
{
{"body", templateBodyAPNS}
};

// Register for push with the Azure mobile app


Push push = TodoItemManager.DefaultManager.CurrentClient.GetPush();
push.RegisterAsync(deviceToken, templates);
}

This method creates a simple notification message template as JSON, and registers the device to receive
template notifications from the notification hub.

The FailedToRegisterForRemoteNotifications override should be implemented to handle


situations such as no network connection. This is important because users might start the application while
offline.

Processing Incoming Push Notifications

The DidReceiveRemoteNotification override in the AppDelegate class is used to process incoming


push notifications when the application is running, and is invoked when a notification is received:

public override void DidReceiveRemoteNotification(


UIApplication application, NSDictionary userInfo,
Action<UIBackgroundFetchResult> completionHandler)
{
NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as
NSDictionary;
string alert = string.Empty;
if (aps.ContainsKey(new NSString("alert")))
alert = (aps[new NSString("alert")] as NSString).ToString();

// Show alert
if (!string.IsNullOrEmpty(alert))
{
UIAlertView avAlert = new UIAlertView("Notification", alert, null,
"OK", null);
avAlert.Show();
}
}

The userInfo dictionary contains the aps key, whose value is the alert dictionary with the remaining
notification data. This dictionary is retrieved, with the string notification message being displayed in a
dialog box.

If an application isn't running when a push notification arrives, the application will be launched but the
DidReceiveRemoteNotification method won't process the notification. Instead, get the notification
payload and respond appropriately from the WillFinishLaunching or FinishedLaunching overrides.

For more information about APNS, see Push Notifications in iOS.

Android

The process for implementing push notification support in an Android application is as follows:

1. Add the Google Cloud Messaging Client component to the Android project, and import the
Gcm.Client namespace into the MainActivity class.
2. Register with Firebase Cloud Messaging (FCM) in the MainActivity.OnCreate method. For
more information, see Registering with Firebase Cloud Messaging.
3. Register with the Azure Notification Hub in the GcmServiceBase.OnRegistered method. For
more information, see Registering with the Azure Notification Hub.
4. Implement the GcmService.OnMessage method to process incoming push notifications. For more
information, see Displaying the Contents of a Push Notification.
5. Implement the GcmService.OnUnregistered and GcmService.OnError methods to de-
register and process errors from FCM. For more information, see De-registering and Processing
Errors.

Registering with Firebase Cloud Messaging

Before an Android application can receive push notifications, it must register with FCM, which will generate
a registration token and return it to the application. Registration is invoked in the OnCreate override in the
MainActivity class:

public class MainActivity :


global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
public static MainActivity CurrentActivity { get; private set; }

protected override void OnCreate(Bundle bundle)


{
...
CurrentActivity = this;
try
{
GcmClient.CheckDevice(this);
GcmClient.CheckManifest(this);
GcmClient.Register(this, PushHandlerBroadcastReceiver.SENDER_IDS);
}
catch (...)
{
...
}
}
...
}

After checking that FCM is supported and that the manifest has the correct information, the application
registers to receive push notifications from FCM. Note that the CurrentActivity property is used to
expose the MainActivity instance, so that the GcmService helper class can perform registration with
the notification hub on the UI thread. This helper class is used to handle interactions with FCM
specifically when registration with FCM succeeds, when the application receives a push notification
message, and when FCM errors occur.

In order to register with FCM, the PushHandlerBroadcastReceiver class defines a public array,
SENDER_IDS, that stores the project number for FCM (obtained from Google Developer Console):

[BroadcastReceiver(Permission = Gcm.Client.Constants.PERMISSION_GCM_INTENTS)]
[IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_MESSAGE },
Categories = new string[] { "@PACKAGE_NAME@" })]
[IntentFilter(new string[] {
Gcm.Client.Constants.INTENT_FROM_GCM_REGISTRATION_CALLBACK }, Categories = new
string[] { "@PACKAGE_NAME@" })]
[IntentFilter(new string[] { Gcm.Client.Constants.INTENT_FROM_GCM_LIBRARY_RETRY
}, Categories = new string[] { "@PACKAGE_NAME@" })]
public class PushHandlerBroadcastReceiver :
GcmBroadcastReceiverBase<GcmService>
{
public static string[] SENDER_IDS = new string[] { "
<INSERT_YOUR_SENDER_ID_HERE>" };
}

The SENDER_IDS array value is used by the GcmService helper class in a call to its base class
constructor:

[Service]
public class GcmService : GcmServiceBase
{
public static string RegistrationToken { get; private set; }

public GcmService() : base(PushHandlerBroadcastReceiver.SENDER_IDS) { }


...
}

The Google Cloud Messaging Client component then uses the value of the SENDER_IDS property stored in
the base class to register with FCM.

Note that the GcmService class should also contain the following permission requests above the
namespace declaration:

[assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]


[assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")]
[assembly: UsesPermission(Name = "com.google.android.c2dm.permission.RECEIVE")]
[assembly: UsesPermission(Name = "android.permission.INTERNET")]
[assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")]
//GET_ACCOUNTS is only needed for android versions 4.0.3 and below
[assembly: UsesPermission(Name = "android.permission.GET_ACCOUNTS")]

Registering with the Azure Notification Hub

The GcmService class implements the GcmServiceBase.OnRegistered method, which is invoked


when an application successfully registers for push notifications with FCM:

[Service]
public class GcmService : GcmServiceBase
{
...
protected override void OnRegistered(Context context, string
registrationToken)
{
Log.Verbose("PushHandlerBroadcastReceiver", "GCM Registered: " +
registrationToken);
RegistrationToken = registrationToken;

var push = TodoItemManager.DefaultManager.CurrentClient.GetPush();


MainActivity.CurrentActivity.RunOnUiThread(() => Register(push, null));
}

public async void Register(Microsoft.WindowsAzure.MobileServices.Push push,


IEnumerable<string> tags)
{
try
{
const string templateBodyGCM = "{\"data\":
{\"message\":\"$(messageParam)\"}}";

JObject templates = new JObject();


templates["genericMessage"] = new JObject
{
{"body", templateBodyGCM}
};
await push.RegisterAsync(RegistrationToken, templates);
Log.Info("Push Installation Id", push.InstallationId.ToString());
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
Debugger.Break();
}
}
...
}

This method stores the returned registration token before invoking the Register method on the UI thread.
The Register method creates a simple notification message template as JSON, and registers the device
to receive template notifications from the notification hub.

Displaying the Contents of a Push Notification

The GcmService class implements the GcmServiceBase.OnMessage method, which is invoked when
FCM sends a push notification to the application:

[Service]
public class GcmService : GcmServiceBase
{
...
protected override void OnMessage(Context context, Intent intent)
{
Log.Info("PushHandlerBroadcastReceiver", "GCM Message Received!");

var msg = new StringBuilder();


if (intent != null && intent.Extras != null)
{
foreach (var key in intent.Extras.KeySet())
msg.AppendLine(key + "=" + intent.Extras.Get(key).ToString());
}

// Retrieve the message


var prefs = GetSharedPreferences(context.PackageName,
FileCreationMode.Private);
var edit = prefs.Edit();
edit.PutString("last_msg", msg.ToString());
edit.Commit();

string message = intent.Extras.GetString("message");


if (!string.IsNullOrEmpty(message))
{
CreateNotification("New todo item!", "Todo item: " + message);
}
}

void CreateNotification(string title, string desc)


{
...
}
}

This method retrieves the message from the notification, and sends it to the notification manager for display
by the CreateNotification method.

De-registering and Processing Errors

The GcmService class implements the GcmServiceBase.OnUnregistered and


GcmServiceBase.OnError methods, which are invoked when the application unregisters from FCM, or
when an errors occurs, respectively:

[Service]
public class GcmService : GcmServiceBase
{
...
protected override void OnUnRegistered(Context context, string
registrationToken)
{
Log.Error("PushHandlerBroadcastReceiver", "Unregistered
RegisterationToken: " + registrationId);
}
protected override void OnError(Context context, string errorId)
{
Log.Error("PushHandlerBroadcastReceiver", "GCM Error: " + errorId);
}
...
}

Both methods log error messages to the Android logs.

For more information about FCM, see Google Cloud Messaging.

Universal Windows Platform

Before a Universal Windows Platform (UWP) application can receive push notifications it must register with
the Windows Notification Service (WNS), which will return a notification channel. Registration is invoked by
the InitNotificationsAsync method in the App class:

private async Task InitNotificationsAsync()


{
var channel = await PushNotificationChannelManager
.CreatePushNotificationChannelForApplicationAsync();

const string templateBodyWNS =


"<toast><visual><binding template=\"ToastText01\"><text
id=\"1\">$(messageParam)</text></binding></visual></toast>";

JObject headers = new JObject();


headers["X-WNS-Type"] = "wns/toast";

JObject templates = new JObject();


templates["genericMessage"] = new JObject
{
{"body", templateBodyWNS},
{"headers", headers} // Needed for WNS.
};

await TodoItemManager.DefaultManager.CurrentClient.GetPush()
.RegisterAsync(channel.Uri, templates);
}
This method gets the push notification channel, creates a notification message template as JSON, and
registers the device to receive template notifications from the notification hub.

The InitNotificationsAsync method is invoked from the OnLaunched override in the App class:

protected override async void OnLaunched(LaunchActivatedEventArgs e)


{
...
await InitNotificationsAsync();
}

This ensures that the push notification registration is created or refreshed every time the application is
launched, therefore ensuring that the WNS push channel is always active.

When a push notification is received it will automatically be displayed as a toast a modeless window
containing the message.

Summary
This article demonstrated how to use Azure Notification Hubs to send push notifications from an Azure
Mobile Apps instance to a Xamarin.Forms application. Azure Notification Hubs provide a scalable push
infrastructure for sending mobile push notifications from any backend to any mobile platform, while
eliminating the complexity of a backend having to communicate with different platform notification systems.

You might also like