Azure Notification Hub is a scalable push notification service that allows sending messages to multiple platforms, including Web Push (VAPID), Apple Push Notification Service (APNs), and Firebase Cloud Messaging (FCM). Recently, we integrated web browser based push notifications into our web application using this service. The journey involved overcoming multiple challenges, from .NET SDK issues to REST API implementation, service worker interactions, and platform-specific limitations, particularly on iOS. This post summarizes our approach, the issues we faced, and the solutions we implemented.
Registering a Web Push Subscription
We implemented a browser service worker to handle push notifications and used the VAPID protocol to securely register subscriptions on the client. More information on service workers can be found here.
navigator.serviceWorker.register("/sw.js").then(async (registration) => { const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: "YOUR_PUBLIC_VAPID_KEY" }); console.log("Push Subscription:", subscription); });
We then sent the subscription object to our backend, which registers our browser with Azure Notification Hub using the Installation API. This allows Azure Notification Hub to send notifications to our browser.
var installation = new { installationId = "unique-user-id", platform = "web", pushChannel = subscription.endpoint, tags = new[] { "user-123" } }; string apiUrl = $"https://{Namespace}.servicebus.windows.net/{HubName}/installations/{installationId}?api-version=2020-06"; string sasToken = GenerateSasToken(apiUrl, SasKeyName, SasKey); -- SasKeyName, SasKey can be obtained from Azure Notification Hub. Code for GenerateSasToken not provided here. string jsonPayload = Newtonsoft.Json.JsonConvert.SerializeObject(installation); var request = new HttpRequestMessage(HttpMethod.Put, apiUrl) { Headers = { { "Authorization", sasToken } }, Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json") }; HttpResponseMessage response = await _httpClient.SendAsync(request);
Service Worker Interactions
The service worker plays a crucial role in receiving and handling push notifications.
self.addEventListener("push", event => { const data = event.data.json(); event.waitUntil( self.registration.showNotification(data.title, { body: data.message, icon: "/icon.png", data: { url: data.url } }) ); });
We also implemented click handling on the notification to open a custom URL when the notification is clicked.
self.addEventListener("notificationclick", event => { event.notification.close(); event.waitUntil(clients.openWindow(event.notification.data.url)); });
Challenges
Here are some of the issues we faced during the implementation:
Issue with the Azure SDK and switching to REST API
The primary problem with the Azure SDK was that it did not match the official documentation, and the version we used was outdated, therefore making it unsuitable for our web push notification implementation.
To gain full control over push subscriptions, we switched to using the Azure Notification Hub REST API. This allowed us to manually register, update, and manage push subscriptions.
Issue with Subject Name in Azure Notification Hub
One major issue we faced was incorrect subject names when configuring VAPID keys in Azure Notification Hub. This resulted in authentication failures. To resolve this, we ensured that the subject name in the VAPID settings matched the expected format required by Azure. The correct format it’s looking for is mailto:[emailaddress], for example mailto:john@hotmail.com.
Handling Push Notifications on iOS
We encountered an issue where push notifications worked on macOS but not on iOS Safari. Some of the solutions we had to implement on iOS were:
- We ensured that our site properly requested notification permissions. The permissions needs to be requested at the click of a button, rather than at page load, which was sufficient for other browser platforms.
- Additionally, on iOS, the permission prompt does not appear unless the website is installed as a PWA. The only way around this is to provide the user of the application with a suitable message/banner for installing the app as a PWA.
Conclusion
Despite the hurdles, the final implementation using Azure Notification Hub works seamlessly across major browsers. The key takeaways were:
- Switching from the Azure SDK to REST API provided more control over subscriptions and tags.
- Service workers played a critical role in handling push events and opening URLs.
- Subject name issues in VAPID caused authentication failures and required proper configuration.
- iOS requires PWA installation for push notifications, unlike macOS or Windows.
If you’re looking to implement Browser based notifications for your website, don’t hesitate to reach out to us.