skip to Main Content

I’m currently trying to implement the Direct Web Push from the Notification Hub from Azure.
However, something seems to be not working, as the Push does not appear and inside Azure I get an "External Notification System Error"

For the Web Push, I’m currently using the "browser" in the ServiceBusNotification-Format.
And this is how I’m calling the SendDirectNotificationAsync.

  var browserSubscriptionEndpoint = registration.Endpoint;
  var browserPushHeaders = new Dictionary<string, string> {
      { "P256DH", registration.P256DH },
      { "Auth", registration.Auth },
    };

  string body = "{"title": "Notification Title", "body":"Notification Hub test notification"}";

  return await _client.SendDirectNotificationAsync(new BrowserNotification(body, browserPushHeaders) {
        Headers = browserPushHeaders,
        }, browserSubscriptionEndpoint);

The request itself succeeds with a 201 OK, I do get a response and inside of the returned result it says that the NotificationOutcome is "enqueued", however, the notification will not be sent out and inside of Azure itself, I will get the error I said before.

Some of the properties of the request are these here:

RequestUri: 'https://testHub.servicebus.windows.net/testHub/messages?api-version=2020-06&direct'
TrackingId: randomTrackingId
ServiceBusNotification-DeviceHandle: https://fcm.googleapis.com/fcm/send/eQA9DO90uUU:test
P256DH: workingP256DHId
Auth: workingAuthId
ServiceBusNotification-Format: browser
traceparent: 00-f6057a955be220cef3f7c7e0fb0d2d4f-661e1efb022a40b0-00
Content-Type: application/json
Content-Length: 79

The response has some of the following properties:

StatusCode: 201, 
ReasonPhrase: 'Created'
Date: Tue, 20 Aug 2024 13:37:11 GMT
Server: Kestrel
Strict-Transport-Security: max-age=2592000
TrackingId: id
x-ms-correlation-request-id: id
X-Powered-By: Azure Notification Hubs
Content-Length: 0

-> It’s not a problem of authorization or of the registration itself not working, as the request goes through and I tried a request with Node.js webpush and postman to the same registration endpoint with the same authorization, vapidkey etc., and I got the push to my browser. So those things should be configured correctly, as far as I’m concerned. But it’s possible that some Azure specific things might not be.

It seems to me that the Package is outdated, as the newest release date was Feb 11, 2022. The BrowserNotification is referenced on the Website, but parts of the implementation were not yet in the actual package itself, they were recently added in the github, but without an official update for the package, so I changed some of the code to match the newest update, but it still seems to not work for me.

2

Answers


  1. In Azure, you can enable diagnostic logs for Notification Hubs. These logs might give you more detailed information on what’s going wrong.

    enter image description here

    • I believe the package has been outdated, consider pulling the latest changes from the GitHub repository and compiling the SDK yourself to ensure you’re using the most up-to-date code. This might resolve any issues stemming from outdated code.

    dotnet add package Microsoft.Azure.NotificationHubs --version 4.2.0

    enter image description here

    There could be many reasons once check the network settings as per your setup. I have worked on this and reproduced the issue please check my below application.

    index.js:

    const express = require('express');
    const webpush = require('web-push');
    const path = require('path');
    
    const app = express();
    
    app.use(express.static(path.join(__dirname, 'public')));
    app.use(express.json());
    
    const vapidKeys = {
        publicKey: 'Your_VAPID_Public_Key',
        privateKey: 'Your_VAPID_Private_Key'
    };
    
    webpush.setVapidDetails(
        'mailto:[email protected]',
        vapidKeys.publicKey,
        vapidKeys.privateKey
    );
    
    app.post('/subscribe', (req, res) => {
        const subscription = req.body;
        res.status(201).json({});
    
        const payload = JSON.stringify({ title: 'Push Test', body: 'This is a test notification' });
    
        webpush.sendNotification(subscription, payload).catch(error => {
            console.error(error.stack);
        });
    });
    
    const port = 3000;
    app.listen(port, () => {
        console.log(`Server running on port ${port}`);
    });
    

    public/index.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Web Push Test</title>
    </head>
    <body>
        <h1>Web Push Test</h1>
        <button id="subscribe">Subscribe to Push Notifications</button>
        <script src="main.js"></script>
    </body>
    </html>
    
    

    // public/main.js:

    const publicVapidKey = 'Your_VAPID_Public_Key';
    
    if ('serviceWorker' in navigator) {
        send().catch(err => console.error(err));
    }
    
    async function send() {
        const register = await navigator.serviceWorker.register('/worker.js', {
            scope: '/'
        });
    
        const subscription = await register.pushManager.subscribe({
            userVisibleOnly: true,
            applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
        });
    
        await fetch('/subscribe', {
            method: 'POST',
            body: JSON.stringify(subscription),
            headers: {
                'Content-Type': 'application/json'
            }
        });
    }
    
    function urlBase64ToUint8Array(base64String) {
        const padding = '='.repeat((4 - base64String.length % 4) % 4);
        const base64 = (base64String + padding)
            .replace(/-/g, '+')
            .replace(/_/g, '/');
        const rawData = window.atob(base64);
        return new Uint8Array(rawData.split('').map(char => char.charCodeAt(0)));
    }
    

    worker.js:

    self.addEventListener('push', event => {
        const data = event.data.json();
        self.registration.showNotification(data.title, {
            body: data.body
        });
    });
    

    Program.cs:

    using Microsoft.Azure.NotificationHubs;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    class Program
    {
        private static string connectionString = "<Your_Notification_Hub_Connection_String>";
        private static string hubName = "<Your_Notification_Hub_Name>";
    
        static async Task Main(string[] args)
        {
            var client = NotificationHubClient.CreateClientFromConnectionString(connectionString, hubName);
    
            var headers = new Dictionary<string, string>
            {
                { "p256dh", "<Client_P256DH_Key>" },
                { "auth", "<Client_Auth_Key>" }
            };
    
            var payload = "{"title": "Test Notification", "body": "This is a test notification from Azure Notification Hub"}";
    
            var notification = new BrowserNotification(payload, headers);
            await client.SendDirectNotificationAsync(notification, "<Client_Endpoint>");
    
            Console.WriteLine("Notification Sent");
        }
    }
    

    Here I able to send push notifications using the web-push library successfully.

    enter image description here

    Login or Signup to reply.
  2. Check that the in the Azure Portal where you can configure the vapid keys for Browser (Web Push), that you have a subject which is an email address with mailto. for example: "mailto:[email protected]" or it could be a url as well i think. See documentation
    If it is just some string, it will fail internally to send notifications but will not give you a proper feedback.
    After you changed the subject you have to wait a while until it starts working. For me it took around 30minutes.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search