Codelab: Compila un cliente de notificaciones push

Kate Jeffreys
Kate Jeffreys
Kayce Basques
Kayce Basques

En este codelab, se muestra paso a paso cómo compilar un cliente de notificaciones push. Al final de este codelab, tendrás un cliente con las siguientes características:

  • Suscribir al usuario a notificaciones push.
  • Recibe mensajes push y los muestra como notificaciones.
  • Anula la suscripción del usuario a las notificaciones push.

Este codelab se enfoca en ayudarte a aprender mediante la práctica y no trata mucho de los conceptos. Consulta ¿Cómo funcionan las notificaciones push? para conocer los conceptos de las notificaciones push.

El código del servidor de este codelab ya está completo. Solo implementarás el cliente en este codelab. Para obtener información sobre cómo implementar un servidor de notificaciones push, consulta el Codelab: Cómo compilar un servidor de notificaciones push.

Consulta push-notifications-client-codelab-complete (fuente) para ver el código completo.

Compatibilidad del navegador

Se sabe que este codelab funciona con las siguientes combinaciones de sistema operativo y navegador:

  • Windows: Chrome y Edge
  • macOS: Chrome y Firefox
  • Android: Chrome y Firefox

Se sabe que este codelab no funciona con los siguientes sistemas operativos (o combinaciones de sistema operativo y navegador):

  • macOS: Brave, Edge, Safari
  • iOS

Configuración

Obtener una copia editable del código

El editor de código que ves a la derecha de estas instrucciones se denominará IU de Glitch a lo largo de este codelab.

  1. Haz clic en Remix para editar para que el proyecto se pueda editar.

Configura la autenticación

Antes de que funcionen las notificaciones push, debes configurar el servidor y el cliente con claves de autenticación. Consulta Firma las solicitudes del protocolo push web para conocer los motivos.

  1. En la IU de Glitch, haz clic en Tools y, luego, en Terminal para abrir la terminal de Glitch.
  2. En la terminal de Glitch, ejecuta npx web-push generate-vapid-keys. Copia los valores de la clave privada y la clave pública.
  3. En la IU de Glitch, abre .env y actualiza VAPID_PUBLIC_KEY y VAPID_PRIVATE_KEY. Establece VAPID_SUBJECT en mailto:test@test.test. Todos estos valores deben estar entre comillas dobles. Después de realizar las actualizaciones, tu archivo .env debería verse similar al siguiente:
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. Cierra la terminal de Glitch.
  1. Abre public/index.js.
  2. Reemplaza VAPID_PUBLIC_KEY_VALUE_HERE por el valor de tu clave pública.

Registra un service worker

Con el tiempo, el cliente necesitará un service worker para recibir y mostrar notificaciones. Es mejor registrar el service worker lo antes posible. Consulta Recibe y muestra los mensajes enviados como notificaciones para obtener más contexto.

  1. Reemplaza el comentario // TODO add startup logic here por el siguiente código:
// TODO add startup logic here
if ('serviceWorker' in navigator && 'PushManager' in window) {
  navigator.serviceWorker.register('./service-worker.js').then(serviceWorkerRegistration => {
    console.info('Service worker was registered.');
    console.info({serviceWorkerRegistration});
  }).catch(error => {
    console.error('An error occurred while registering the service worker.');
    console.error(error);
  });
  subscribeButton.disabled = false;
} else {
  console.error('Browser does not support service workers or push messages.');
}

subscribeButton.addEventListener('click', subscribeButtonHandler);
unsubscribeButton.addEventListener('click', unsubscribeButtonHandler);
  1. Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona Pantalla completa pantalla completa.
  1. Presiona `Control + Mayúsculas + J` (o `Command + Option + J` en Mac) para abrir Herramientas para desarrolladores.
  2. Haz clic en la pestaña Consola. Deberías ver el mensaje Service worker was registered. registrado en Console.

Cómo solicitar permisos de notificaciones push

Nunca debes solicitar permiso para enviar notificaciones push cuando se carga la página. En cambio, tu IU debería preguntarle al usuario si desea recibir notificaciones push. Una vez que se confirme de manera explícita (por ejemplo, con un clic en un botón), puedes iniciar el proceso formal para obtener el permiso de notificaciones push del navegador.

  1. En la IU de Glitch, haz clic en View Source para volver al código.
  2. En public/index.js, reemplaza el comentario // TODO de subscribeButtonHandler() por el siguiente código:
// TODO
// Prevent the user from clicking the subscribe button multiple times.
subscribeButton.disabled = true;
const result = await Notification.requestPermission();
if (result === 'denied') {
  console.error('The user explicitly denied the permission request.');
  return;
}
if (result === 'granted') {
  console.info('The user accepted the permission request.');
}
  1. Regresa a la pestaña de la app y haz clic en Suscríbete a push. Es probable que tu navegador o sistema operativo te pregunte si quieres permitir que el sitio web te envíe notificaciones push. Haz clic en Permitir (o cualquier frase equivalente que use tu navegador o SO). En la consola, deberías ver un mensaje que indica si se aceptó o rechazó la solicitud.

Suscribirse a las notificaciones push

El proceso de suscripción implica la interacción con un servicio web controlado por el proveedor del navegador que se denomina servicio push. Una vez que obtengas la información de la suscripción a las notificaciones push, deberás enviarla a un servidor y hacer que este la almacene en una base de datos a largo plazo. Consulta Cómo suscribir al cliente a notificaciones push para obtener más contexto sobre el proceso de suscripción.

  1. Agrega el siguiente código destacado a subscribeButtonHandler():
subscribeButton.disabled = true;
const result = await Notification.requestPermission();
if (result === 'denied') {
  console.error('The user explicitly denied the permission request.');
  return;
}
if (result === 'granted') {
  console.info('The user accepted the permission request.');
}
const registration = await navigator.serviceWorker.getRegistration();
const subscribed = await registration.pushManager.getSubscription();
if (subscribed) {
  console.info('User is already subscribed.');
  notifyMeButton.disabled = false;
  unsubscribeButton.disabled = false;
  return;
}
const subscription = await registration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: urlB64ToUint8Array(VAPID_PUBLIC_KEY)
});
notifyMeButton.disabled = false;
fetch('/add-subscription', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(subscription)
});

La opción userVisibleOnly debe ser true. Es posible que algún día sea posible enviar mensajes sin mostrar notificaciones visibles para el usuario (inserciones silenciosas), pero actualmente los navegadores no permiten esa función debido a cuestiones de privacidad.

El valor applicationServerKey se basa en una función de utilidad que convierte una string base64 en un Uint8Array. Este valor se usa para la autenticación entre tu servidor y el servicio de envío.

Cómo anular la suscripción a las notificaciones push

Después de que un usuario se suscribe a las notificaciones push, tu IU debe proporcionar una forma de anular la suscripción en caso de que cambie de opinión y ya no quiera recibir notificaciones push.

  1. Reemplaza el comentario // TODO en unsubscribeButtonHandler() por el siguiente código:
// TODO
const registration = await navigator.serviceWorker.getRegistration();
const subscription = await registration.pushManager.getSubscription();
fetch('/remove-subscription', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({endpoint: subscription.endpoint})
});
const unsubscribed = await subscription.unsubscribe();
if (unsubscribed) {
  console.info('Successfully unsubscribed from push notifications.');
  unsubscribeButton.disabled = true;
  subscribeButton.disabled = false;
  notifyMeButton.disabled = true;
}

Recibir un mensaje push y mostrarlo como una notificación

Como se mencionó antes, necesitas un service worker para controlar la recepción y la visualización de los mensajes que se enviaron al cliente desde tu servidor. Consulta Recibe y muestra los mensajes enviados como notificaciones para obtener más detalles.

  1. Abre public/service-worker.js y reemplaza el comentario // TODO en el controlador de eventos push del service worker por el siguiente código:
// TODO
let data = event.data.json();
const image = 'https://cdn.glitch.com/614286c9-b4fc-4303-a6a9-a4cef0601b74%2Flogo.png?v=1605150951230';
const options = {
  body: data.options.body,
  icon: image
}
self.registration.showNotification(
  data.title, 
  options
);
  1. Regresa a la pestaña de la app.
  2. Haz clic en Notificarme. Deberías recibir una notificación push.
  3. Intenta abrir la URL de la pestaña de la app en otros navegadores (o incluso en otros dispositivos), sigue el flujo de trabajo de suscripción y, luego, haz clic en Notificar a todo. Deberías recibir la misma notificación push en todos los navegadores a los que te suscribiste. Consulta Compatibilidad con navegadores para ver una lista de las combinaciones de navegador/SO que se sabe que funcionan o no.

Puedes personalizar la notificación de muchas maneras. Consulta los parámetros de ServiceWorkerRegistration.showNotification() para obtener más información.

Cómo abrir una URL cuando un usuario hace clic en una notificación

En el mundo real, es probable que uses la notificación como una manera de volver a atraer al usuario y pedirle que visite tu sitio. Para hacer eso, necesitas configurar un poco más el service worker.

  1. Reemplaza el comentario // TODO en el controlador de eventos notificationclick del service worker por el siguiente código:
// TODO
event.notification.close();
event.waitUntil(self.clients.openWindow('https://web.dev'));
  1. Regresa a la pestaña de la app, envíate otra notificación y haz clic en ella. El navegador debería abrir una pestaña nueva y cargar https://web.dev.

Próximos pasos