Notificaciones automáticas en su app web

Cómo crear notificaciones automáticas para su próxima aplicación web.

Notificaciones automáticas — Es posible que se encuentre con situaciones en las que necesite enviar a los usuarios un recordatorio o un boletín informativo por correo electrónico. hoy construiremos un sistema que se ejecuta en segundo plano de su aplicación Node js para enviar notificaciones a los usuarios.


Trabajaremos con colas específicamente BullMQ, una biblioteca que resuelve muchos problemas de una manera elegante. Ya tengo una aplicación instalada en React y Nodejs conectado a una base de datos MongoDB.

Intentaremos enviar notificaciones automáticas al usuario para informarle que tiene todo hoy. Puede trabajar alrededor de esto para satisfacer sus necesidades como lo desee.

  • Configuración del proyecto Firebase

Cree un nuevo proyecto de Firebase y, en nuestro caso, seleccionaremos la opción web para registrar nuestra nueva aplicación web.

En su aplicación React, instale Firebase ejecutando el siguiente comando en su terminal:

npm install firebase

Cree un archivo, llámelo firebase.js y pegue el código de instalación y configuración de su SDK.

import { initializeApp } from "firebase/app";

const firebaseConfig = {
  apiKey: "AIzaSyB3Qz4_yyZdQAynG56sgSkuUkwjWzJTPwFE",
  authDomain: "test-medium-notification.firebaseapp.com",
  projectId: "test-medium-notification",
  storageBucket: "test-medium-notification.appspot.com",
  messagingSenderId: "960445380697883",
  appId: "1:9604445386973:web:6142826be7a79c552b9ccb34"
}; // change this to your configuration

const firebaseApp = initializeApp(firebaseConfig);

Nota: oculte sus claves almacenándolas en un archivo .env para la seguridad de la aplicación. No voy a ocultar el mío porque voy a eliminar la aplicación después de que se publique este artículo jajaja. 🙂

  • Habilitación de la mensajería en la nube

Hay dos pasos que debemos realizar antes de habilitar Firebase Cloud Messaging:

  • Clave de servidor de API de mensajería en la nube
  • Clave de certificados Web Push

En la configuración de su proyecto, haga clic en “Administrar API en Google Cloud Console”, esto lo redirigirá a la consola de mensajería de Firebase Cloud, haga clic en habilitar para habilitar el uso de su API, y aquí es donde realizaremos un seguimiento de las solicitudes de los usuarios.

Haga clic en habilitar.

Ahora que tenemos la primera clave, que es la clave del servidor, la usaremos para realizar una solicitud posterior a la API de FCM.


Desplácese hacia abajo en la misma página, el siguiente paso es hacer clic en “Generar par de claves”.

Esta clave se usa como el segundo parámetro de la función getToken como vapidKey.

import { getMessaging, getToken, onMessage } from "firebase/messaging";
const messaging = getMessaging(firebaseApp);
const getTokenn = (setNotifyToken, userId) => {
   return getToken(messaging, {
   //change to your public key
    vapidKey: 'BJahpd6CqZxpeUtNXZagHC5rUxCeGqhgTyRCncmgj9_zNQlXedZjFTQBFlhHcsHWXyx6xGXtv-9NgMppVie-BLI'}).then(async 	(currentToken) => {
   if (currentToken) {
      console.log(currentToken) // log token for test
   setNotifyToken(currentToken)
    // here we will store our user token in our database 
   await axios.post('/updateUserToken', { userId, notifyToken: currentToken}); 
   // Track the token -> client mapping, by sending to backend server
   // show on the UI that permission is secured
} else { setNotifyToken('');
// shows on the UI that permission is required
}}).catch((err) => {
   console.log('An error occurred while retrieving token. ', err); });
}
const onMessageListener = () =>
  new Promise((resolve) => {
  onMessage(messaging, (payload) => {resolve(payload);
});
  });
export {
  getTokenn,
  onMessageListener
}

Diríjase al archivo firebase.js y pega este código:

// Scripts for firebase and firebase messaging
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-messaging-compat.js');
// Initialize the Firebase app in the service worker by passing the generated config

const firebaseConfig = {
  apiKey: "AIzaSyB3Qz4_yyZdQAynG56sgSkuUkwjWzJTPwFE",
  authDomain: "test-medium-notification.firebaseapp.com",
  projectId: "test-medium-notification",
  storageBucket: "test-medium-notification.appspot.com",
  messagingSenderId: "960445380697883",
  appId: "1:9604445386973:web:6142826be7a79c552b9ccb34"
}; // change this to your configuration

firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();

messaging.onBackgroundMessage(function(payload) {
console.log('Received background message ', payload);
const notificationTitle = payload.notification.title;

const notificationOptions = {
body: payload.notification.body,
};

self.registration.showNotification(notificationTitle,
notificationOptions);
});

En su directorio público, cree un archivo llamado firebase-messaging-sw.js y pegue este código y cambie la variable firebaseConfig.

import { getTokenn } from '../firebase.js';

const [notifyToken, setNotifyToken] = useState(''); 

const loginUser = async () => {
  const { data: { data: {
    user: loggedUser,
    token,
    message } } } = await axios.post('login',
        { email: user.email, password: user.password });  
  getTokenn(setNotifyToken, loggedUser.id) // send token with user id find user and store token
  
}); 
}}
}

Aquí, estoy almacenando el token de usuario después del inicio de sesión del usuario, puede cambiar esto como desee, pero en mi caso, llamaré a getToken al iniciar sesión y registrarme. notificarToken tendrá el estado del token.

notificaciones automáticas

Ahora, cuando un usuario inicia sesión, el navegador debe promocionar un cuadro que le pide al usuario que permita las notificaciones. haga clic en permitir.

notificaciones automáticas

Probemos nuestra mensajería en la nube enviando un mensaje de prueba a este usuario.

notificaciones automáticas

Copie el token de usuario de las herramientas de desarrollo de la consola y navegue a la consola en la nube de Firebase y toque la opción Mensajes y luego haga clic en “Crear su primera campaña”.

notificaciones automáticas

Marque la primera opción, porque queremos que los usuarios reciban alertas fuera de nuestra aplicación.

notificaciones automáticas

Agregue el título y el cuerpo del texto a su mensaje y presione “Enviar mensaje de prueba”.

notificaciones automáticas

Agregue el token de usuario como un nuevo dispositivo y presione “Probar”.

notificaciones automáticas

El mensaje recibido debería verse así.


Ahora que configuramos la mensajería en la nube y almacenamos un token único para cada usuario, vamos a crear nuestro programador, usaremos BullMQ.

En su aplicación node js, primero debe tener Redis instalado en su máquina para poder usar BullMQ.

Aquí hay una fuente para que los usuarios de ubuntu instalen Redis.

 

https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-20-04

 

Instale BullMQ con este comando:

npm install bullmq
const { Queue, Worker } = require('bullmq');
const { Todo } = require('../database/models/todo.model');
const { User } = require('../database/models/user.model');
  const redisConfiguration = {
   connection: {
    host: "localhost",
    port: 6379, // default redis port
  }}
const taskQueue = async () => {
  const todos = await Todo.find({
  notification: true,
  isNotified: false,
  state: "open"
  }) // get all todos from database that is hasn't been notified yet

  // add jobs to the queue   
  const myQueue = new Queue('todosSchedule', redisConfiguration);
  await myQueue.add('alert', todos, { repeat: false });
  
  // process the jobs in your workers   
  let worker = new Worker('todosSchedule', async (job) => {
      todos.map(async (task, index) => {
      const response = await axios.post('https://fcm.googleapis.com/fcm/send',{
      notification:{
        title: `You have this ${task.title} today`},
      to: task.userToken},{
      headers: {
      'Authorization': 'key={YOUR_SERVER_KEY}'}})
      
      if (response.status === 200) {
        todos.splice(index, 1) // remove element from array
        
        await Todo.updateOne({ // update todo in db
          _id: task.id
        }, {
          notification: false,
          isNotified: true,});
        }})
      }, redisConfiguration);
      
      // track job progress 
      worker.on('completed', async job => {
      console.log("job success")
      });
      worker.on('progress', job => {
      console.info('job is in progress!');
      });
      worker.on('failed', (job, err) => {
      console.error('job has error!');
      });
  
      setTimeout(() => {
      taskQueue()}, 60000 * 5) // run job every 5 minutes
  }

taskQueue()

Cree un módulo, llámelo taskQueue.js y pegue el código anterior.


Aquí tengo todas las tareas pendientes en la base de datos con el usuario que las creó como token de usuario y una notificación, isNotified y state open son propiedades en el modelo Todo, actualizamos estas propiedades después de que el envío del mensaje se realiza correctamente.

El último paso es que necesitamos ejecutar taskQueue.js y dirigirnos a app.js y solicitar el módulo.

app.get(require('./taskQueue'));

Gracias por llegar hasta aquí, si encuentras esto útil no olvides aplaudir 👍🏼suscribirse para recibir más contenido.

Si le interesa, puede echar un vistazo a algunos de los otros artículos que he escrito recientemente sobre AWS y Laravel:

Recent Post