Search code examples
xamarin.formsxamarin.iosapple-push-notificationsazure-notificationhub

iOS Push Notifications with Azure Notification Hub


I am having absolutely no luck getting push notifications to work in iOS in a Xamarin Forms project.

In AppDelegate.cs, I am calling the following in the FinishedLaunching override:

MSNotificationHub.Start("Endpoint=sb://[redacted].servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=[redacted]",
                        "[redacted]");

After the user logs in further in the app lifecycle, I also register the user with their user tag as follows:

    public async Task UpdateTags(string token)
    {
        await Task.Run(() =>
        {
            try
            {
                // No point registering tags until the user has signed in and we have a device token
                if (CurrentAccount == null)
                {
                    Console.WriteLine($"UpdateTags cancelled: Account is null");
                    return;
                }
                var tag = $"user:{CurrentAccount.UserName}";
                Console.WriteLine($"Registering tag: {tag}");
                MSNotificationHub.AddTag(tag);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error registering tag: {e.ToString()}");
            }
        });
    }

I have properly configured the Apple (APNS) settings in the notification hub, using the Token authentication mode (verified the four fields several times). The certificate (signing identity) is "iOS Distribution", the identifier bundle matches exactly what I have in the configuration (not using wildcard), the key has Apple Push Notifications service (APNs) enabled, and the provisioning profile has Platform: iOS and Type: App Store.

I pushed the application to TestFlight, as I don't have access to a physical Mac (we use a Cloud mac for development). When I view the device logs from my personal iPhone with the app installed, I see the following when I run it:

<Notice>: Registered for push notifications with token: [redacted]
<Notice>: Registering tag: user:[redacted]

There are no instances of "Error registering tag" or "UpdateTags cancelled" in the logs at all, which tells me that the method calls are succeeding without an exception. However, when I attempt to send a test notification to either a blank/empty tag, or the specific tag for my test user, no notifications are received and the messaging simply shows "Message was successfully sent, but there were no matching targets."

Also, when I pull all of the registrations with var registrations = await hub.GetAllRegistrationsAsync(0);, I only see the FCM (Firebase/Android) registrations from my successful testing on the Android side of things.

I am at a complete loss and have hit a wall, as there are no exceptions being thrown, and seemingly no way to troubleshoot what is going on behind the scenes.

This is also my 2nd attempt - I was using a more complex SBNotificationHub implementation and had the same results - no exceptions and everything looked fine at face value.


Solution

  • Thanks to a comment pointing to another question, I have determined that all I needed to do was to ensure that my tag registration ran on the main UI thread. My updated code below is working:

        public async Task UpdateTags(string token)
        {
            await Task.Run(() =>
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    try
                    {
                        // No point registering tags until the user has signed in and we have a device token
                        if (CurrentAccount == null)
                        {
                            Console.WriteLine($"UpdateTags cancelled: Account: {Trico.OrbitalApp.App.CurrentAccount};");
                            return;
                        }
                        var tag = $"user:{CurrentAccount.UserName}";
                        Console.WriteLine($"Registering tag: {tag}");
                        MSNotificationHub.AddTag(tag);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine($"Error registering device: {e.ToString()}");
                    }
                });
            });
        }