Tutorial: Push notifications to Xamarin.Android apps using Azure Notification Hubs

Overview

This tutorial shows you how to use Azure Notification Hubs to send push notifications to a Xamarin.Android application. You create a blank Xamarin.Android app that receives push notifications by using Firebase Cloud Messaging (FCM). You use your notification hub to broadcast push notifications to all the devices running your app. The finished code is available in the NotificationHubs app sample.

In this tutorial, you take the following steps:

  • Create a Firebase project and enable Firebase Cloud Messaging
  • Create a notification hub
  • Create a Xamarin.Android app and connect it to the notification hub
  • Send test notifications from the Azure portal

Prerequisites

Create a Firebase project and enable Firebase Cloud Messaging

  1. Sign in to the Firebase console. Create a new Firebase project if you don't already have one.
  2. After you create your project, select Add Firebase to your Android app. Then follow the instructions that are provided. Download google-services.json file.

    Add Firebase to your Android app

  3. In the Firebase console, select the cog for your project. Then select Project Settings.

    Select Project Settings

  4. Select the General tab in your project settings. Then download the google-services.json file that contains the Server API key and Client ID.
  5. Select the Cloud Messaging tab in your project settings, and then copy the value of the Legacy server key. You use this value to configure the notification hub access policy.

Create a notification hub

  1. Sign in to the Azure portal.

  2. Select Create a resource > Mobile > Notification Hub.

    Azure portal - create a notification hub

  3. In the Notification Hub box, type a unique name. Select your Region, Subscription, and Resource Group (if you have one already).

    If you don't already have a service bus namespace, you can use the default name, which is created based on the hub name (if the namespace name is available).

    If you already have a service bus namespace that you want to create the hub in, follow these steps

    a. In the Namespace area, select the Select Existing link.

    b. Select Create.

    Azure portal - set notification hub properties

  4. Select Notifications (Bell icon), and select Go to resource.

    Azure portal - notifications -> Go to resource

  5. Select Access Policies from the list. Note the two connection strings that are available to you. You need them to handle push notifications later.

    Important

    Do NOT use the DefaultFullSharedAccessSignature in your application. This is meant to be used in your back-end only.

    Azure portal - notification hub connection strings

Configure GCM settings for the notification hub

  1. Select Google (GCM) in the NOTIFICATION SETTINGS section.
  2. Enter the Legacy server key you noted down from the Google Firebase Console.
  3. Select Save on the toolbar.

Your notification hub is configured to work with FCM, and you have the connection strings to both register your app to receive notifications and to send push notifications.

Create Xamarin.Android app and connect it to notification hub

Create Visual Studio project and add NuGet packages

  1. In Visual Studio, point to File, select New, and then select Project.

    Visual Studio- Create new Android project

  2. In the Solution Explorer window, expand Properties, and click AndroidManifest.xml. Update the package name to match the package name you entered when adding Firebase Cloud Messaging to your project in the Google Firebase Console.

    Package name in GCM

  3. Right-click your project, and select Manage NuGet Packages....
  4. Select the Browse tab. Search for Xamarin.GooglePlayServices.Base. Select Xamarin.GooglePlayServices.Base in the result list. Then, select Install.

    Google Play Services NuGet

  5. In the NuGet Package Manager window, search for Xamarin.Firebase.Messaging. Select Xamarin.Firebase.Messaging in the result list. Then, select Install.
  6. Now, search for Xamarin.Azure.NotificationHubs.Android. Select Xamarin.Azure.NotificationHubs.Android in the result list. Then, select Install.

Add the Google Services JSON File

  1. Copy google-services.json that you downloaded from the Google Firebase Console to the project folder.
  2. Add google-services.json to the project.
  3. Select google-services.json in the Solution Explorer window.
  4. In the Properties pane, set the Build Action to GoogleServicesJson. If you don't see GoogleServicesJson, close Visual Studio, relaunch it, reopen the project, and retry.

    GoogleServicesJson build action

Set up notification hubs in your project

Registering with Firebase Cloud Messaging

Open the AndroidManifest.xml file and insert the following <receiver> elements into the <application> element:

    <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
    <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" 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="${applicationId}" />
      </intent-filter>
    </receiver>
  1. Gather the following information for your Android app and notification hub:

    • Listen connection string: On the dashboard in the Azure portal, choose View connection strings. Copy the DefaultListenSharedAccessSignature connection string for this value.
    • Hub name: Name of your hub from the Azure portal. For example, mynotificationhub2.
  2. Right-click your project in the Solution Explorer window, point to Add, and select Class.

  3. Create a Constants.cs class for your Xamarin project and define the following constant values in the class. Replace the placeholders with your values.

        public static class Constants
        {
           public const string ListenConnectionString = "<Listen connection string>";
           public const string NotificationHubName = "<hub name>";
        }
    
  4. Add the following using statements to MainActivity.cs:

        using Android.Util;
    
  5. Add an instance variable to MainActivity.cs that will be used to show an alert dialog when the app is running:

        public const string TAG = "MainActivity";
    
  6. Add the following code to OnCreate in MainActivity.cs after base.OnCreate(savedInstanceState):

        if (Intent.Extras != null)
        {
            foreach (var key in Intent.Extras.KeySet())
            {
                if(key!=null)
                {
                    var value = Intent.Extras.GetString(key);
                    Log.Debug(TAG, "Key: {0} Value: {1}", key, value);
                }
            }
        }
    
  7. Create a new class, MyFirebaseIIDService like you created the Constants class.
  8. Add the following using statements to MyFirebaseIIDService.cs:

    using Android.App;
    using Android.Util;
    using WindowsAzure.Messaging;
    using Firebase.Iid;
    
  9. In MyFirebaseIIDService.cs, add the following class declaration, and have your class inherit from FirebaseInstanceIdService:

        [Service]
        [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
        public class MyFirebaseIIDService : FirebaseInstanceIdService
    
  10. In MyFirebaseIIDService.cs, add the following code:

        const string TAG = "MyFirebaseIIDService";
        NotificationHub hub;
    
        public override void OnTokenRefresh()
        {
            var refreshedToken = FirebaseInstanceId.Instance.Token;
            Log.Debug(TAG, "FCM token: " + refreshedToken);
            SendRegistrationToServer(refreshedToken);
        }
    
        void SendRegistrationToServer(string token)
        {
            // Register with Notification Hubs
            hub = new NotificationHub(Constants.NotificationHubName,
                                      Constants.ListenConnectionString, this);
    
            var tags = new List<string>() { };
            var regID = hub.Register(token, tags.ToArray()).RegistrationId;
    
            Log.Debug(TAG, $"Successful registration of ID {regID}");
        }
    
  11. Create another new class for your project, name it MyFirebaseMessagingService.
  12. Add the following using statements to MyFirebaseMessagingService.cs.

        using Android.App;
        using Android.Util;
        using Firebase.Messaging;
    
  13. Add the following above your class declaration, and have your class inherit from FirebaseMessagingService:

        [Service]
        [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
        public class MyFirebaseMessagingService : FirebaseMessagingService
    
  14. Add the following code to MyFirebaseMessagingService.cs:

        const string TAG = "MyFirebaseMsgService";
        public override void OnMessageReceived(RemoteMessage message)
        {
            Log.Debug(TAG, "From: " + message.From);
            if(message.GetNotification()!= null)
            {
                //These is how most messages will be received
                Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
                SendNotification(message.GetNotification().Body);
            }
            else 
            {
                //Only used for debugging payloads sent from the Azure portal
                SendNotification(message.Data.Values.First());
    
            }
    
        }
    
        void SendNotification(string messageBody)
        {
            var intent = new Intent(this, typeof(MainActivity));
            intent.AddFlags(ActivityFlags.ClearTop);
            var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
    
            var notificationBuilder = new Notification.Builder(this)
                        .SetContentTitle("FCM Message")
                        .SetSmallIcon(Resource.Drawable.ic_launcher)
                        .SetContentText(messageBody)
                        .SetAutoCancel(true)
                        .SetContentIntent(pendingIntent);
    
            var notificationManager = NotificationManager.FromContext(this);
    
            notificationManager.Notify(0, notificationBuilder.Build());
        }
    
  15. Build your project.
  16. Run your app on your device or loaded emulator

Send test notification from the Azure portal

You can test receiving notifications in your app with the Test Send option in the Azure portal. It sends a test push notification to your device.

Azure portal - Test Send

Push notifications are normally sent in a back-end service like Mobile Services or ASP.NET through a compatible library. If a library is not available for your back-end, you can also use the REST API directly to send notification messages.

Next steps

In this tutorial, you sent broadcast notifications to all your Android devices registered with the backend. To learn how to push notifications to specific Android devices, advance to the following tutorial: