Implementación de Notificaciones Push con la Web Push API

Las notificaciones push mantienen a los usuarios comprometidos incluso cuando no están usando activamente tu aplicación web. La Web Push API te permite enviar actualizaciones oportunas directamente a los dispositivos de los usuarios sin depender de servicios de terceros. Esta guía muestra cómo implementar notificaciones nativas utilizando Service Workers, autenticación VAPID y cifrado adecuado.
Puntos Clave
- La Web Push API permite notificaciones push nativas sin servicios de terceros
- Los Service Workers y la autenticación VAPID son componentes esenciales
- La conexión HTTPS es obligatoria para la implementación
- Los diferentes navegadores tienen requisitos variables para las notificaciones push
Requisitos Previos y Compatibilidad con Navegadores
Antes de implementar notificaciones push, asegúrate de que tu aplicación cumpla con estos requisitos:
- Conexión HTTPS (requerida para Service Workers)
- Compatibilidad con navegadores modernos (Chrome, Firefox, Edge, Safari 16.4+)
- Compatibilidad con Service Worker
// Feature detection
if ('serviceWorker' in navigator && 'PushManager' in window) {
// Push notifications supported
}
Registrando un Service Worker
El Service Worker actúa como un proxy entre tu aplicación web y los servicios push. Regístralo durante la carga de la página:
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('Service Worker registered:', registration);
})
.catch(error => {
console.error('Registration failed:', error);
});
Configuración de Claves VAPID
VAPID (Voluntary Application Server Identification) autentica tu servidor con los servicios push. Genera un par de claves una vez para tu aplicación:
# Using web-push library (Node.js)
npm install web-push
npx web-push generate-vapid-keys
Almacena la clave privada de forma segura en tu servidor y utiliza la clave pública en tu suscripción del lado del cliente.
Creación de Suscripciones Push
Solicita permiso y suscribe a los usuarios a las notificaciones push:
async function subscribeToPush() {
const registration = await navigator.serviceWorker.ready;
// Request permission (only on user gesture)
const permission = await Notification.requestPermission();
if (permission !== 'granted') return;
// Subscribe with VAPID public key
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
});
// Send subscription to your server
await fetch('/api/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(subscription)
});
}
// Helper function to convert base64 to Uint8Array
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
El objeto de suscripción contiene:
- Endpoint: URL única para enviar mensajes
- Keys: Claves de cifrado (p256dh y auth) para la seguridad de la carga útil
Discover how at OpenReplay.com.
Implementación del Lado del Servidor
Tu servidor debe cifrar los mensajes y enviarlos al endpoint del servicio push. Usar la librería web-push simplifica esto:
const webpush = require('web-push');
webpush.setVapidDetails(
'mailto:your-email@example.com',
VAPID_PUBLIC_KEY,
VAPID_PRIVATE_KEY
);
// Send notification
const payload = JSON.stringify({
title: 'New Message',
body: 'You have a new update',
icon: '/icon-192.png',
url: 'https://example.com/updates'
});
webpush.sendNotification(subscription, payload, {
TTL: 86400, // 24 hours
urgency: 'high'
})
.catch(error => {
console.error('Error sending notification:', error);
});
Manejo de Eventos Push en el Service Worker
El Service Worker recibe y muestra las notificaciones push:
// sw.js
self.addEventListener('push', event => {
const data = event.data?.json() || {};
const options = {
body: data.body || 'Default message',
icon: data.icon || '/icon.png',
badge: '/badge.png',
vibrate: [200, 100, 200],
data: { url: data.url }
};
event.waitUntil(
self.registration.showNotification(data.title || 'Notification', options)
);
});
// Handle notification clicks
self.addEventListener('notificationclick', event => {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data?.url || '/')
);
});
Requisitos Específicos por Navegador
Los diferentes navegadores imponen requisitos variables para la implementación de la Web Push API:
- Chrome/Edge: Requieren notificaciones visibles para cada mensaje push
- Firefox: Permite push silencioso limitado con sistema de cuotas
- Safari: Requiere notificaciones visibles y no admite push silencioso
Nota: Los tamaños de carga útil están limitados: Chrome/Edge/Firefox admiten hasta 4KB, mientras que Safari admite 2KB. Mantén los mensajes ligeros y obtén datos adicionales en la aplicación si es necesario.
Siempre muestra las notificaciones inmediatamente al recibir eventos push para mantener los permisos en todos los navegadores.
Mejores Prácticas de Seguridad
Protege tu implementación de notificaciones push:
- Endpoints seguros: Nunca expongas públicamente los endpoints de suscripción
- Cifra las cargas útiles: Todos los datos de mensajes deben usar cifrado ECDH
- Protege las claves VAPID: Almacénalas de forma segura y regenera solo si están comprometidas
- Implementa protección CSRF: Valida las solicitudes de suscripción
- Limitación de tasa: Previene el abuso con limitación del lado del servidor
Gestión del Ciclo de Vida de la Suscripción
Maneja los cambios y la expiración de la suscripción:
// In Service Worker
self.addEventListener('pushsubscriptionchange', event => {
event.waitUntil(
self.registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
})
.then(subscription => {
// Update server with new subscription
return fetch('/api/update-subscription', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(subscription)
});
})
);
});
Conclusión
La Web Push API proporciona un enfoque basado en estándares para implementar notificaciones push sin dependencia de proveedores. Al combinar Service Workers, autenticación VAPID y cifrado adecuado, puedes entregar notificaciones oportunas que funcionan en navegadores modernos. Recuerda respetar las preferencias del usuario, manejar eventos del ciclo de vida de la suscripción y seguir los requisitos específicos de cada plataforma para una implementación robusta.
Comienza con la entrega básica de notificaciones y luego agrega características como botones de acción, adjuntos de imágenes y agrupación de notificaciones a medida que tu implementación madure.
Preguntas Frecuentes
No, las notificaciones push requieren una conexión a internet activa para recibir mensajes del servicio push. Sin embargo, los Service Workers pueden almacenar en caché las notificaciones y mostrarlas cuando regrese la conectividad.
Cuando se deniega el permiso, no puedes enviar notificaciones push a ese usuario. Debes esperar a que cambien manualmente los permisos en la configuración del navegador. Considera implementar métodos alternativos de participación como notificaciones dentro de la aplicación.
La mayoría de los servicios push limitan el tamaño de la carga útil a 4KB. Chrome y Firefox admiten hasta 4KB, mientras que Safari admite hasta 2KB. Mantén las cargas útiles mínimas y obtén datos adicionales cuando se reciba la notificación si es necesario.
Sí, las notificaciones push pueden recibirse cuando el navegador está cerrado en la mayoría de las plataformas. Sin embargo, esto depende del sistema operativo y del navegador. Los navegadores móviles pueden tener restricciones basadas en la configuración de optimización de batería.
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.