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 del codelab, tendrás un cliente que:

  • Suscribe al usuario a las 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 con la práctica y no habla mucho sobre conceptos. Lee Cómo funcionan las notificaciones push para obtener información sobre los conceptos de las notificaciones push.

El código del servidor de este codelab ya está completo. En este codelab, solo implementarás el cliente. Para aprender a implementar un servidor de notificaciones push, consulta el codelab: Cómo compilar un servidor de notificaciones push.

Compatibilidad del navegador

Este codelab funciona con las siguientes combinaciones de sistema operativo y navegador:

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

Este codelab no funciona con los siguientes sistemas operativos (o combinaciones de sistema operativo y navegador):

  • macOS: Brave, Edge y Safari
  • iOS

Configuración

Configura la autenticación

Antes de que las notificaciones push funcionen, debes configurar tu servidor y cliente con claves de autenticación. Consulta Firma tus solicitudes de protocolo web push para conocer el motivo. Por lo general, los secretos se almacenan en un archivo .env, similar a este.

VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. Abre public/index.js.
  2. Reemplaza VAPID_PUBLIC_KEY_VALUE_HERE por el valor de tu clave pública.

Registra un service worker

Tu cliente necesita un service worker para recibir y mostrar notificaciones. Lo mejor es registrar el service worker lo antes posible. Consulta Recibe y muestra los mensajes push como notificaciones para obtener más contexto.

  1. Reemplaza el comentario // TODO add startup logic here por el siguiente código:

    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);
    
  2. En Chrome, abre la consola de Herramientas para desarrolladores.

  3. Deberías ver el mensaje Service worker was registered. registrado en la consola.

Solicitar permisos de notificaciones push

Nunca debes solicitar permiso para enviar notificaciones push cuando se carga la página. En su lugar, la IU debería preguntarle al usuario si desea recibir notificaciones push. Una vez que lo confirmen de forma explícita (por ejemplo, haciendo clic en un botón), podrás iniciar el proceso formal para obtener el permiso de notificaciones push del navegador.

  1. En public/index.js, reemplaza el comentario // TODO en subscribeButtonHandler() por el siguiente código:

    // 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.');
    }
    
  2. Regresa a la pestaña de la app y haz clic en Subscribe to push. Tu navegador o sistema operativo te preguntará si quieres permitir que el sitio web te envíe notificaciones push.

  3. Selecciona Permitir (o la frase equivalente que use tu navegador o sistema operativo). 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 interactuar con un servicio web controlado por el proveedor del navegador, que se denomina servicio push. Una vez que obtengas la información de 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.

  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 se puedan enviar mensajes push sin mostrar notificaciones visibles para el usuario (mensajes push silenciosos), pero los navegadores no permiten esa función debido a inquietudes sobre la privacidad.

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

Anular la suscripción a las notificaciones push

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

  • Reemplaza el comentario // TODO en unsubscribeButtonHandler() por el siguiente código:
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;
}

Recibe un mensaje push y muéstralo como una notificación

Como se mencionó antes, necesitas un service worker para controlar la recepción y visualización de los mensajes que se enviaron al cliente desde tu servidor. Consulta Recibe y muestra los mensajes push 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:

    let data = event.data.json();
    const image = 'logo.png';
    const options = {
      body: data.options.body,
      icon: image
    }
    self.registration.showNotification(
      data.title,
      options
    );
    
  2. Regresa a la pestaña de la app.

  3. Haz clic en Notificarme. Deberías recibir una notificación push.

  4. Abre la URL de la pestaña de tu app en otros navegadores compatibles. Sigue el flujo de trabajo de suscripción y haz clic en Notificar a todos. Deberías recibir la misma notificación push en cada uno.

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

Abre una URL cuando un usuario hace clic en una notificación

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

  1. Reemplaza el comentario // TODO en el controlador de eventos notificationclick del service worker por el siguiente código:

    event.notification.close();
    event.waitUntil(self.clients.openWindow('https://web.dev'));
    
  2. Regresa a la pestaña de la app, envíate otra notificación y, luego, haz clic en ella. El navegador debería abrir una pestaña nueva y cargar https://web.dev.

Próximos pasos