Milèstre BV
Aug 21, 2020

Xamarin Forms: Update Notification Tags with Azure Notification Hub



Normally when you install a new app that supports push notifications with Azure Notification Hub, a new token is generated after first startup. At that moment tags are registered as well.

But what if you want to update these notifications tag on a later moment, for instance after a login? Then you have to update the tag!

How can you do that?

I am using the NotificationHubSample, Microsoft has created. You can find it here: https://github.com/xamarin/xamarin-forms-samples/tree/master/WebServices/AzureNotificationHub/NotificationHubSample

As soon as the new token is generated, we have to store it secure because we need it during update of the notification tags:

In Android in FirebaseService.cs:

public async override void OnNewToken(string token)

{

    SendRegistrationToServer(token);

    await SecureStorage.SetAsync("newnotificationtoken", "true");

}

In iOS in AppDelegate.cs:

public override async void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)

{

    try

    {

        Hub = new SBNotificationHub(General.ListenConnectionString, General.NotificationHubName);

 

        // update registration with Azure Notification Hub

        Hub.UnregisterAll(deviceToken, (error) =>

        {

            if (error != null)

            {

                Crashes.TrackError(new System.InvalidOperationException($"Unable to call unregister {error}"));

                return;

            }

 

            var tags = new NSSet(General.SubscriptionTags.ToArray());

            Hub.RegisterNative(deviceToken, tags, (errorCallback) =>

            {

                if (errorCallback != null)

                {

                    Crashes.TrackError(new System.InvalidOperationException($"RegisterNativeAsync error: {errorCallback}"));

                }

            });

 

            var templateExpiration = DateTime.Now.AddDays(120).ToString(System.Globalization.CultureInfo.CreateSpecificCulture("en-US"));

            Hub.RegisterTemplate(deviceToken, "defaultTemplate", General.APNTemplateBody, templateExpiration, tags, (errorCallback) =>

            {

                if (errorCallback != null)

                {

                    if (errorCallback != null)

                    {

                        Crashes.TrackError(new System.InvalidOperationException($"RegisterTemplateAsync error: {errorCallback}"));

                    }

                }

            });

 

        });

 
        //convert it to a base64 string that can be stored and used later when you want to update the tag

        string token = deviceToken.getBase64EncodedString(NSDataBase64EncodingOptions.None);

        await SecureStorage.SetAsync("notificationtoken", token);

 

    } catch (Exception ex)

    {

        Crashes.TrackError(ex));

    }

} 

Then we are going to create Dependency objects in Android and iOS.

First create an interface class in you shared project

namespace Xamarin_Support.Interfaces

{

    public interface INotificationHelper

    {

        void UpdateToken(string token, string[] subscriptionTags);

    }

}

In Android project create a new dependency object NotificationHelper, that is based on the above interface class.

using notification_App.Droid.Helpers;

using Plugin.CurrentActivity;

using System.Threading.Tasks;

using WindowsAzure.Messaging;

using Xamarin.Forms;

using Xamarin_Support.Helpers;

using Xamarin_Support.Interfaces;

 

[assembly: Dependency(typeof(NotificationHelper))]

namespace notification_App.Droid.Helpers

{

    public class NotificationHelper : INotificationHelper

    {

        public async void UpdateToken(string token, string[] subscriptionTags)

        {

            NotificationHub hub = new NotificationHub(General.NotificationHubName, General.ListenConnectionString, CrossCurrentActivity.Current.Activity);

 

            //run on different thread, not on ui thread to prevent an exception

            await Task.Run(() => {

                //First unregister from current tags

                hub.Unregister();

                // register new tags with Azure Notification Hub using the token from FCM

                hub.Register(token, subscriptionTags);

            });

        }

    }

} 

In iOS project also, create a new dependency object NotificationHelper, that is based on the above interface class.

using notification_App.iOS.Helpers;

using Foundation;

using Microsoft.AppCenter.Crashes;

using System.Linq;

using WindowsAzure.Messaging;

using Xamarin.Forms;

using Xamarin_Support.Helpers;

using Xamarin_Support.Interfaces;

 

[assembly: Dependency(typeof(NotificationHelper))]

namespace notification_App.iOS.Helpers

{

    public class NotificationHelper : INotificationHelper

    {

        public void UpdateToken(string token, string[] subscriptionTags)

        {

            SBNotificationHub Hub = new SBNotificationHub(General.ListenConnectionString, General.NotificationHubName);

 

            NSData deviceToken = new NSData(token, NSDataBase64DecodingOptions.None);

            Hub.UnregisterAll(deviceToken, (error) =>

            {

                if (error != null)

                {

                    Crashes.TrackError(new System.InvalidOperationException($"Unable to call unregister {error}"));

                    return;

                }

 

                var tags = new NSSet(subscriptionTags.ToArray());

                Hub.RegisterNative(deviceToken, tags, (errorCallback) =>

                {

                    if (errorCallback != null)

                    {

                        Crashes.TrackError(new System.InvalidOperationException($"RegisterNativeAsync error: {errorCallback}"));

                    }

                });

            });

        }

    }

} 

Now you are ready to update the notification tags, whereever you want, for instance after a succesfull login:

INotificationHelper notificationHelper = DependencyService.Get<INotificationHelper>();

//get the sored token

string notificationToken = await SecureStorage.GetAsync("notificationtoken");

//create new tag array

string[] subscriptionTags = new string[] { customerId };


//update tags

notificationHelper.UpdateToken(notificationToken, subscriptionTags); 



About us

Milèstre is a digital development agency based in Maastricht and operating all over the world. Since 2003 we build software solutions together with established companies and great startups. During the years we have developed a process that enables us to transform ideas into meaningful, intelligent and designfull experiences for mobile and web. A process where strategy, design, development and user experience are playing an important rol.

 

Contact us

Milestre BV
Ambyerstraat Zuid 82
6225 AJ Maastricht
Netherlands

Tel: +31(0)43 - 4070780
Email: info@milestre.nl
Recent Posts

© Copyright 2022 - Milestre BV
Top