Push Notifications: How Your App Speaks When It’s Sleeping
What are Push Notifications ? Push notifications are messages sent from an app or website to a user's device, even when the app or site isn’t actively open. They appear as pop-up alerts, banners, or notification icons on devices like smartphones, tablets, and computers. The mechanism with which these "Push Notifications" work is usually the use of some sort of background processes, these processes maintain a persistent connection with the designated "Push Server" depending on their device (in the case of Native Push) or their navigator (in the case of Web Push). There's two types of Push Notifications: Native Push: This one usually is linked directly to the Operating System of the Device where Push notifications were activated, for example, Windows, MacOS, Android or IOS. Web Push: This one is linked to specific navigators instead of the OS directly, Firefox, Chrome (or any Chromium based navigator like Opera...), Firefox etc... There is a difference between both the execution and implementation of these two types. Web Push Web Push is a Protocol/technology that allows websites to send push notifications to users’ devices (desktop, mobile) even when the browser is closed. It’s part of the Push API and Notifications API standards, because it's not tightly coupled with the OS, sometimes it could not work as proficiently. On some mobile OSes, browsers may be restricted from running background processes aggressively to save battery, causing delays or missed notifications. Native Push The Native one works the greatest because Push Notifications are considered Top Priority by the OS, meaning that as long as the user has actual internet connection, they will 100% receive that Push notification, unless they go out of their way to tamper with the settings concerning those notifications or maybe they simply deactivate them. Wrappers They’re libraries or services that abstract the differences between native push services (like Apple Push Notification Service for iOS, Firebase Cloud Messaging for Android, Windows Notification Service, and Web Push for browsers) so you can send notifications without writing separate code for each platform. The issue with these "wrappers" is summarized in two things: Due to the abstractions offered by third-party wrappers, a new problem could arise, instead of fully operating your system/mechanism, you rely on a third party service. These "wrapper" services usually either cost money or are "fremiums" (meaning they are free for a certain amount of traffic/messages, after that it becomes paid once it passes a certain threshold) Push Server One of the most important components when it comes to push notifications is the "Push Server". The way it works is that we subscribe a device for a specific app/notification etc., which generates a very Unique URL, the vendor-specific server registers that this specific device "subscribed" to listen for push notifications coming on that navigator/device, the Unique URL generated gets stored in the backend so that we send a request to it, which in turns gets the actual vendor-specific server to push those notifications to those devices, So in very simple words, it's just a middleman, we don't get the right to directly push notifications from the backend to the device. Push Notifications usually operate with a Pub/Sub Architecture Subscribers: are the devices that want to receive notifications. Broker: being the Push Server that mediates between the Broadcaster (Backend) and the actual subscribed clients. Publisher(s): the backend that wants to broadcast events/messages (new discounts etc.) There are Push Servers that handle notifications for each OS/Browser: The Diagram above demonstrates the common Native Push Servers for each platform/browser (on the left), and it also shows how wrappers could be used to hide all that technical implementation behind abstractions that end up offering the developers very simplified API endpoints/library methods to use (on the far right) Advantages of Push Notifications: One of the main advantages is the ability to distribute specific messages/notifications to devices/browsers that aren’t currently open or in use. If there are multiple Websites/apps that use the same vendor-specific server to push their notifications to devices, then a singular connection gets persisted with multiple "Publishers" but with the same "Broker" which minimizes back-and-forth Network communication, for this reason Multiplexing is used to minimize battery drain, especially on phones. Example(s) of Use Cases: 1) An admin needs to be notified immediately when a new order is placed, even if the browser or device is idle or closed. Push notifications ensure that the admin receives timely updates regardless of the app’s active state. 2) A user needs to know when a new message is received. While real-time communication methods like WebSockets

What are Push Notifications ?
Push notifications are messages sent from an app or website to a user's device, even when the app or site isn’t actively open. They appear as pop-up alerts, banners, or notification icons on devices like smartphones, tablets, and computers.
The mechanism with which these "Push Notifications" work is usually the use of some sort of background processes, these processes maintain a persistent connection with the designated "Push Server" depending on their device (in the case of Native Push) or their navigator (in the case of Web Push).
There's two types of Push Notifications:
- Native Push: This one usually is linked directly to the Operating System of the Device where Push notifications were activated, for example, Windows, MacOS, Android or IOS.
- Web Push: This one is linked to specific navigators instead of the OS directly, Firefox, Chrome (or any Chromium based navigator like Opera...), Firefox etc...
There is a difference between both the execution and implementation of these two types.
Web Push
Web Push is a Protocol/technology that allows websites to send push notifications to users’ devices (desktop, mobile) even when the browser is closed. It’s part of the Push API and Notifications API standards, because it's not tightly coupled with the OS, sometimes it could not work as proficiently.
On some mobile OSes, browsers may be restricted from running background processes aggressively to save battery, causing delays or missed notifications.
Native Push
The Native one works the greatest because Push Notifications are considered Top Priority by the OS, meaning that as long as the user has actual internet connection, they will 100% receive that Push notification, unless they go out of their way to tamper with the settings concerning those notifications or maybe they simply deactivate them.
Wrappers
They’re libraries or services that abstract the differences between native push services (like Apple Push Notification Service for iOS, Firebase Cloud Messaging for Android, Windows Notification Service, and Web Push for browsers) so you can send notifications without writing separate code for each platform. The issue with these "wrappers" is summarized in two things:
- Due to the abstractions offered by third-party wrappers, a new problem could arise, instead of fully operating your system/mechanism, you rely on a third party service.
- These "wrapper" services usually either cost money or are "fremiums" (meaning they are free for a certain amount of traffic/messages, after that it becomes paid once it passes a certain threshold)
Push Server
One of the most important components when it comes to push notifications is the "Push Server". The way it works is that we subscribe a device for a specific app/notification etc., which generates a very Unique URL, the vendor-specific server registers that this specific device "subscribed" to listen for push notifications coming on that navigator/device, the Unique URL generated gets stored in the backend so that we send a request to it, which in turns gets the actual vendor-specific server to push those notifications to those devices, So in very simple words, it's just a middleman, we don't get the right to directly push notifications from the backend to the device.
Push Notifications usually operate with a Pub/Sub Architecture
- Subscribers: are the devices that want to receive notifications.
- Broker: being the Push Server that mediates between the Broadcaster (Backend) and the actual subscribed clients.
- Publisher(s): the backend that wants to broadcast events/messages (new discounts etc.)
There are Push Servers that handle notifications for each OS/Browser:
- The Diagram above demonstrates the common Native Push Servers for each platform/browser (on the left), and it also shows how wrappers could be used to hide all that technical implementation behind abstractions that end up offering the developers very simplified API endpoints/library methods to use (on the far right)
Advantages of Push Notifications:
- One of the main advantages is the ability to distribute specific messages/notifications to devices/browsers that aren’t currently open or in use.
- If there are multiple Websites/apps that use the same vendor-specific server to push their notifications to devices, then a singular connection gets persisted with multiple "Publishers" but with the same "Broker" which minimizes back-and-forth Network communication, for this reason Multiplexing is used to minimize battery drain, especially on phones.
Example(s) of Use Cases:
1) An admin needs to be notified immediately when a new order is placed, even if the browser or device is idle or closed. Push notifications ensure that the admin receives timely updates regardless of the app’s active state.
2) A user needs to know when a new message is received. While real-time communication methods like WebSockets, Polling, or Server-Sent Events (SSE) work when the app is open, they fail when the window is minimized or fully closed. In such cases, push notifications become the most reliable strategy.
Setting up: WebPush
To setup WebPush on your web server, we're going to use a minimal wrapper library called "web-push" (it exists in NodeJS, Python and PHP and there are other implementations aswell).
There are 2 major sections:
1 - Backend
Now each website/API is identified with a pair of VAPID keys (Voluntary Application Server Identification), In order for our Web server to send push notifications, VAPID keys are used to authenticate the web server to the push server.
- To generate the VAPID keys, we run the following instruction:
const webPush = require("web-push");
console.log(webPush.generateVAPIDKeys());
// response:
/* {
publicKey: 'BENBPj_33ywKcH109jfokUTiS91pLbD2SmVNbUja9KBN4Ppn8HTuZNC_TKEGGsJLRzx4X02kiNA7I-7uKYnLwRM',
privateKey: '0LLLufPFBBXYFWOymFzrrLkLFeh0GTJzZ-XKf-Ehe_w'
} */
- We set those details with this function:
webPush.setVapidDetails(
`mailto:${process.env.PRIMARY_EMAIL_OF_MENTAINER}`,
vapidKeys.publicKey,
vapidKeys.privateKey
);
- Now we need 2 methods.
- One Method for adding the "Push Endpoints" for each app/device (aka the subscribers)
- One other method is for sending the actual Push Notification.
let subscribers = [];
function setNewAdminSubscription(sub) {
subscribers.push(sub);
console.log("new subscription")
}
function sendAdminsNotification(message=null) {
for (let adminSub of subscribers) {
webPush.sendNotification(adminSub, "Test");
}
}
2 - Frontend
Okay on the front end we have to setup 2 things.
- A Service Worker, which is basically a type of process that runs in the background, it's seperated from the web page itself, so it can do background fetching, handle push notifications and other things..
A Function to Subscribe, This would accomplish two things, show an "allow notifications ?" popup to show up, and also subscribe to the designated "Push Server" (depending on which navigator is being used).
For the service worker we create a file named "sw.js" (or any other name, it doesn't matter)
This handles the push notification in a way that it shows a popup and specifies the vibration settings (if the navigator is on a phone) etc etc.. basically customizing the popup that will show up.
// sw.js
self.addEventListener('push', (e) => {
var options = {
body: 'This notification is a teest',
icon: 'images/example.jpg',
vibrate: [100, 50, 100],
// data: {
// dateOfArrival: Date.now(),
// primaryKey: '2'
// },
// sticky: true,
requireInteraction: true,
actions: [
{
action: 'explore',
title: 'Explore this new world',
icon: 'images/checkmark.jpg'
},
{ action: 'close', title: 'Close', icon: 'images/xmark.png' }
]
};
e.waitUntil(self.registration.showNotification('Hello World', options));
});
- Now to actually register it within the website, you have to run this code in the index.js (if you're using an SPA like React), or maybe index.html (inside a |script| block)
// index.js
/* ... */
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App/>
</StrictMode>,
)
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(function (registration) {
console.log('Service Worker Registered.');
});
navigator.serviceWorker.ready.then(function (registration) {
console.log('Service Worker Ready');
});
}
- Now this would be the actual subscribe action:
async function subscribe() {
let sw = await navigator.serviceWorker.ready;
let push = await sw.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: ' '
});
await axios.post('/subscribe-push', push);
}
At this point you're basically done, all you have to do now is incorporate the "sendPushNotification" method in critical parts of your backend.
In an E-commerce website it could be a simple "new order has been created!" notification when an order has been created (on a Model/ORM/T-SQL Level) or it could be of other uses.
1) The Client makes a purchase (aka confirms an order)
2) The Web Server then logs the successful order in a Database (using an ORM or a Native DB-Adapter), then using the method we defined, the backend initializes a Push Notification to the Push Server
3) The Push Server then Pushes the notification to the Admin's Browser
The point is that you could broadcast any notification to anyone, conditional statements could be added to make sure specific notifications get sent to specific "User-Agents" and so on.