Push Notification

The Web Push API relies on a service worker to catch notifications pushed from the server.

At the Node.js back-end, this uses the web-push package, which inherently utilizes the Firebase Messaging service. You can consider using Pushover too.
RESETRUNFULL
// server.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var fs = require('fs');
var http = require('http');
var https = require('https');
const webPush = require('web-push');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// VAPID keys should only be generated only once.
// const vapidKeys = webPush.generateVAPIDKeys();
var vapidPublic = 'BP_6miS1aKl……B04xr8';
var vapidPrivate = 'ZPMo7IB3……FE1o';
webPush.setVapidDetails(
  'https://my-site.com/',
  vapidPublic,  // process.env.VAPID_PUBLIC_KEY,
  vapidPrivate   //process.env.VAPID_PRIVATE_KEY
);
var subscriptions = {};
var pushInterval = 10;  // 10s

function sendNotification(subscription) {
  webPush.sendNotification(subscription)
  .then(function() {
     console.log('Push Application Server - Notification sent to ' + subscription.endpoint);
  }).catch(function() {
     console.log('ERROR in sending Notification, endpoint removed ' + subscription.endpoint);
     delete subscriptions[subscription.endpoint];
  });
}

app.get('/vapidPublicKey', function(req, res) {
   res.send(vapidPublic);
});

app.post('/register', function(req, res) {
   var subscription = req.body.subscription;
   if (!subscriptions[subscription.endpoint]) {
      console.log('Subscription registered ' + subscription.endpoint);
      subscriptions[subscription.endpoint] = subscription;
   }
   res.sendStatus(201);
});

app.post( '/unregister', function(req, res) {
   var subscription = req.body.subscription;
   if (subscriptions[subscription.endpoint]) {
      console.log('Subscription unregistered ' + subscription.endpoint);
      delete subscriptions[subscription.endpoint];
   }
   res.sendStatus(201);
});

app.get('/:file', async function(req,res,next){
   res.sendFile(__dirname+'\\'+req.params.file);
});

var ssl_options = {
   ca: [fs.readFileSync('../ssl/cert1.crt','utf-8'),
        fs.readFileSync('../ssl/cert2.crt','utf-8'),
        fs.readFileSync('../ssl/cert3.crt','utf-8')],
   key: fs.readFileSync('../ssl/mykey.key','utf-8'),
   cert: fs.readFileSync('../ssl/mycert.crt','utf-8')
};

var server = https.createServer(ssl_options,app);
server.listen(443,"0.0.0.0");

setInterval(function() {
  Object.values(subscriptions).forEach(sendNotification);
}, pushInterval * 1000);

// service-worker.js
self.addEventListener('push', function(event) {
   event.waitUntil(
      self.registration
          .showNotification('ServiceWorker Cookbook', {
            lang: 'en',
            body: 'Please be notified that you have been notified.',
            icon: 'doraemon.jpg',
            vibrate: [500, 100, 500],
      })
   );
});

self.addEventListener('notificationclick', function(event) {
   event.waitUntil(
      clients.matchAll().then(function(clis) {
         var client = clis.find(c=>(c.visibilityState === 'visible'));   // tab is active
         // console.log(client,clis);
         if (!client) {
            client.navigate('push.html');
            client.focus();
         } else {  // browser/tab not open
            clients.openWindow('push.html');
            event.notification.close();
         }
      })
   );
 });

<!DOCTYPE html><html lang="en">
<body>
   <button id='subscribe' onclick="register()">Subscribe</button>
   <button id='unsubscribe' onclick="unregister()">UnSubscribe</button>
   <script>
      var subscription=null;
      function urlBase64ToUint8Array(base64String) {
         var padding = '='.repeat((4 - base64String.length % 4) % 4);
         var base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');
         var rawData = window.atob(base64);
         var outputArray = new Uint8Array(rawData.length);
         for (var i = 0; i < rawData.length; ++i) {
            outputArray[i] = rawData.charCodeAt(i);
         }
         return outputArray;
      }
      function register(){
         fetch('./register', {
            method: 'post',
            headers: {'Content-type': 'application/json'},
            body: JSON.stringify({subscription: subscription}),
         });
      }
      function unregister(){
         fetch('./unregister', {
            method: 'post',
            headers: {'Content-type': 'application/json'},
            body: JSON.stringify({subscription: subscription}),
         });
      }
      navigator.serviceWorker.register('./service-worker.js');
      navigator.serviceWorker.ready.then(async function(registration) {
         subscription = await registration.pushManager.getSubscription();
         if (!subscription){
            const response = await fetch('vapidPublicKey');
            const vapidPublicKey = await response.text();
            const convertedVapidKey = urlBase64ToUint8Array(vapidPublicKey);
            subscription = await registration.pushManager.subscribe({
               userVisibleOnly: true,
               applicationServerKey: convertedVapidKey
            });
         }
      });
   </script>
</body></html>

To run the Node.js application:

npm init -y npm install express web-push body-parser node server.js

Then launch the site on a browser by entering into the address box:

https://mysite.com/push.html

To receive the notifications, make sure you have enabled the option to receive them on your browser. This can be done, for instance, by long-pressing the browser icon on your Android device and switching the Notifications setting. On Windows PC, you will need to go the Notifications settings:

You will also need to make sure you have allowed notifications to be sent from the URL on the browser settings.