Think of web push notifications like this:
Your Website -> Browser Company Server -> User Browser -> Notification PopupYour website does not directly send notifications to the browser.
Instead:
- Chrome uses Google servers
- Firefox uses Mozilla servers
- Safari uses Apple servers
These servers act like delivery agents.
Real-Life Analogy
Imagine:
You = Restaurant
Google/FCM = Delivery Company
User = CustomerFlow:
Restaurant prepares food
↓
Delivery company picks it up
↓
Delivery company delivers to customerSimilarly:
Your server creates notification
↓
Browser push service receives it
↓
Browser delivers it to userThe Complete Flow
Step 1: User Visits Your Website
User opens:
https://example.comYour website asks:
"Can I send notifications?"Browser popup appears:
Allow notifications/
[Allow] [Block]If user clicks Allow, browser starts setting things up.
Step 2: Browser Creates a Push Subscription
This is the Most Important part.
The browser creates a special object called:
Push SubscriptionIt contains:
{
"endpoint": "https://fcm.googleapis.com/fcm/send/abc123",
"keys": {
"p256dh": "...",
"auth": "..."
}
}What Is This Endpoint?
The endpoint is basically:
The delivery address of this browserLike:
House Address:
Flat 202, DelhiBut digitally.
Example:
https://fcm.googleapis.com/fcm/send/abc123This means:
"If you want to send notifications to THIS browser, send them here."Important:
This endpoint belogs to:
- Chrome/Google
- Firefox/Mozilla
- Safari/Apple
Not your server.
Step 3: Your Website Sends Subscription to Your Backend
Frontend sends this object to your server.
Example:
fetch('/save-subscription', {
method: 'POST',
body: JSON.stringify(subscription)
});Your backend stores it in database.
Example:
| User | Endpoint |
|---|---|
| John | https://fcm.googleapis.com/... |
Step 4: Something Happens
Suppose:
- User gets message
- Order shipped
- New comment arrives
Your beckend decides:
"I should notify the user."Step 5: Your Server Sends Notification to Google/FCM
This is where people get confused.
Your server does NOT send notification directly to browser.
Instead:
Your Server
↓
Google FCM Server
↓
Chrome BrowserYour backend sends request to:
https://fcm.googleapis.com/fcm/send/abc123using code like:
webpush.sendNotification(subscription, payload);What Is FCM?
FCM means:
Firebase Cloud MessagingGoogle runs it.
Chrome browsers stay connected to Google servers all the time.
So Google already knows:
- where browser is
- whether device is online
- how to take browser efficiently
Why This Middle Layer Exists
Imagine every website directly connected to every browser.
Impossible.
Instead:
Browser keeps ONE connection with GoogleGoogle handles delivery for millions of websites.
This:
- saves battery
- reduces internet usage
- improves scalability
Step 5: Browser Receives Push
Google sends push to Chrome.
Chrome wakes up:
Service WorkerWhat Is Service Worker?
Service Worker is background JavaScript.
It runs EVEN when:
- website closed
- tab closed
- browser minimized
Think of it like:
Background mini-app inside browserService Worker Receives Push
Example:
self.addEventListener('push', event => {
console.log('Push received');
});Browser says:
"Hey service worker, new notification arrived."Step 7: Service Worker Shows Notification
Now service worker displays popup:
self.registration.showNotification("New Message", {
body: "You got a message"
});User sees:
🔔 New Message
You got a messageThink of Browser Push Service Like WhatsApp Servers
You do NOT send WhatsApp messages directly to another phone.
You send:
Your Phone -> WhatsApp Server -> Other PhoneSimilarly:
Your Server -> Google Push Server -> BrowserWhy Push Notifications Are Efficient
Without push:
- browser repeatedly asks server
With push:
- server sends only when needed
This saves:
- battery
- CPU
- bandwidth
What Is the Usage of VAPID?
VAPID is used to identify and authenticate your server when sending web push notifications.
VAPID stands for:
Voluntary Application Server Identification
When your backend sends a push notification, it sends it to:
- Google (Chrome)
- Mozilla (Firefox)
- Apple (Safari)
These companies need to know:
"Who is sending this push notification?"VAPID provides that identity.
Without VAPID
Imagine anybody on the internet could send push notifications pretending to be your website.
That would cause:
- spam
- fake notifications
- abuse
- phising attacks
So push service require:
- sender identification
- authentication
VAPID Solves This Problem
Your server proves:
"I am the real owner of this application."using:
- Public Key
- Private Key
Main Usage of VAPID
1 Identify Your Server
When sending notification:
Your Server -> Google FCMGoogle checks:
"Which application server is this?"VAPID answers that.
2 Authenticate Push Requests
Your server digitally signs requests using:
- private key
Push service verifies signature using:
- public key
Like:
Digital signature verification3 Prevent Fake Notifications
Without VAPID:
Anyone could send fake pushesWith VAPID:
Only authenticated servers can send notificationsWorking of VAPID
Step 1: You Generate VAPID Keys
You create:
Public Key
Private KeyExample:
const vapidKeys = webpush.generateVAPIDKeys();Output:
Public Key:
BEl62i...
Private Key:
kXz91...What These Keys Mean
Public Key:
Shared with browser.
It identifies your application.
Private Key:
Stored only on backend.
It signs push requests
Real-Life Analogy:
Public Key = Username
Private Key = Password/SignatureStep 2: Browser Uses Your Public Key
Frontend code:
registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: PUBLIC_KEY
});Browser now knows:
"This subscription belongs to this application server."What Browser Does Internally
Browser:
- contacts push service
- creates subscription
- associates it with your pubic key
Example:
{
"endpoint": "https://fcm.googleapis.com/fcm/send/abc123"
}Google stores internally:
Subscription abc123 belongs to PUBLIC_KEY xyzThis is very important.
Step 3: Your Backend Sends Notification
Now suppose user receives message.
Backend sends push:
webpush.sendNotification(subscription, payload);What Happens Internally Here
Before sending request:
library creates:
JWT tokenThis token contains:
- who is sending
- expiration
- audience
Example:
{
"aud": "https://fcm.googleapis.com",
"exp": 1710000000,
"sub": "mailto:test@example.com"
}Step 4: JWT Is Signed Using Private Key
Your backend signs JWT using:
PRIVATE_KEYThis creates:
Digital SignatureLike signing a legal document.
Why Signature Matters
Because only YOU have:
- private key
So only you can create valid signature.
Step 5: Google Verifies Signature
Google receives:
Push Request
+ JWT Token
+ Public KeyNow Google checks:
Can this signature be verified using this public key?If Yes:
Sender is authenticPush accepted.
If No:
Fake senderPush rejected.
Important Cryptography Idea
This is called:
Public-Key CryptographyRule:
Data signed with private key
can only be verified with matching public key
Leave a comment
Your email address will not be published. Required fields are marked *


