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.
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.
Probemos nuestra mensajería en la nube enviando un mensaje de prueba a este usuario.
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”.
Marque la primera opción, porque queremos que los usuarios reciban alertas fuera de nuestra aplicación.
Agregue el título y el cuerpo del texto a su mensaje y presione “Enviar mensaje de prueba”.
Agregue el token de usuario como un nuevo dispositivo y presione “Probar”.
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: