Node.js 有条件地向特定用户发送web推送通知
我愿意在我的web应用程序上使用web推送通知。我已经在前端(React)设置了serviceWorkers,并在后端(NodeJS)实现了web推送通知。现在我只需要发送特定于用户的通知,这意味着只有特定的用户才能收到这些通知 例如,在我的web应用程序的后端,我将收到一些实时值。比如说,有一个名为 “用户”,其中存储所有用户数据。现在,这些用户将有一个名为“device”的字段,用户将在其中接收数字值,该值将在40-50秒内更新 现在,它们将成为这些值的阈值。例如,如果值达到200以上,则特定用户应收到推送通知,让他们知道设备已达到其极限 我如何才能创建这样的特定于用户的推送通知,其中通知将仅发送给设备值已达到200以上的用户?。另外,我正在使用Mongoose作为数据库 前端代码(react.js) sw.js:Node.js 有条件地向特定用户发送web推送通知,node.js,reactjs,service-worker,web-push,push-api,Node.js,Reactjs,Service Worker,Web Push,Push Api,我愿意在我的web应用程序上使用web推送通知。我已经在前端(React)设置了serviceWorkers,并在后端(NodeJS)实现了web推送通知。现在我只需要发送特定于用户的通知,这意味着只有特定的用户才能收到这些通知 例如,在我的web应用程序的后端,我将收到一些实时值。比如说,有一个名为 “用户”,其中存储所有用户数据。现在,这些用户将有一个名为“device”的字段,用户将在其中接收数字值,该值将在40-50秒内更新 现在,它们将成为这些值的阈值。例如,如果值达到200以上,则特
self.addEventListener("notificationclick", function (event) {
// on Notification click
let notification = event.notification;
let action = event.action;
console.log("Notification====>", notification);
if (action === "confirm") {
console.log("Confirm clicked");
notification.close(); // Closes the notifcation
} else {
event.waitUntil(
clients.matchAll().then(function (clis) {
var client = clis.find(function (c) {
return c.visibilityState === "visible";
});
if (client !== undefined) {
// found open window
client.navigate("http://localhost:3000"); // means website opens on the same tab where user is on
client.focus();
} else {
// if client's window was not open
clients.openWindow("http://localhost:3000"); // when browser window is closed, open website
}
notification.close();
})
);
console.log(action); // name of action, basically id
}
});
self.addEventListener("notificationclose", function (event) {
console.log("Notification closed", event);
});
// triggers when we get an incoming push message
self.addEventListener("push", function (event) {
console.log("Push notifications recieved from eventListner", event);
var data = { title: "New!", content: "New things" };
if (event.data) {
// check if payload exists(from backend)
data = JSON.parse(event.data.text()); // recieve payload & store
}
var options = {
body: data.content,
icon: "https://iconarchive.com/download/i90141/icons8/windows-8/Cinema-Avengers.ico",
tag: "id1",
renotify: true,
};
event.waitUntil(self.registration.showNotification(data.title, options));
});
swReg.js:
if ("serviceWorker" in navigator) {
console.log("Registering service worker");
navigator.serviceWorker
.register("/sw.js")
.then(() => {
console.log("Service Worker has been registered");
})
.catch((err) => console.error(err));
}
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;
}
function displayConfirmNotification() {
if ("serviceWorker" in navigator) {
const options = {
body: "After subscription managing done",
// icon: "/src/assets/img/pattern_react.png",
// tag:"" ==> in advanced options.
vibrate: [100, 50, 200],
// badge:""
tag: "confirm",
renotify: true,
actions: [
{ action: "confirm", title: "okay" }, // optnl icon:""
{ action: "cancel", title: "cancel" },
],
};
navigator.serviceWorker.ready.then(function (swreg) {
swreg.showNotification("Successfully subscribed sW", options);
});
}
}
function configPushSub() {
if (!("serviceWorker" in navigator)) {
return;
}
var reg;
navigator.serviceWorker.ready
.then(function (swreg) {
// access to sW registration
reg = swreg;
return swreg.pushManager.getSubscription(); // returns any existing subscription
})
.then(function (sub) {
// sub holds the current subscription, if subscription doesn't exist then it returns null
if (sub === null) {
// Create a new subscription
var vapidPublicKey = KEY;
var convertedPublicKey = urlBase64ToUint8Array(vapidPublicKey);
return reg.pushManager.subscribe({
userVisibleOnly: true, // for security
applicationServerKey: convertedPublicKey, // for security & server storage
}); // create new subscription
} else {
// We already have a subscription
}
})
.then(function (newSub) {
// have to pass this subscription(new one) to backend
console.log("New subb =======>", newSub);
return fetch("http://localhost:8000/subscribeToPushNotifications", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
subscriptionObj: newSub,
}),
});
})
.then(function (res) {
if (res.ok) {
displayConfirmNotification();
}
})
.catch(function (e) {
console.log("err while subbing====>", e);
});
}
function askForNotificationPermission() {
Notification.requestPermission(function (result) {
console.log("User's choice", result);
if (result !== "granted") {
console.log("Permission rights not granted");
} else {
configPushSub();
// displayConfirmNotification();
}
});
}
if ("Notification" in window) {
askForNotificationPermission();
}
检查值是否超过阈值,然后发送通知:(例如)。这是一个仅针对单个用户的示例
exports.checkStatus = async () => {
schedule.scheduleJob("*/10 * * * * *", async () => {
let subscriptions = await Subscription.find({});
let Email = "james@mail.com";
let findUser = await User.findOne({ Email });
if (findUser) {
if (findUser.device > 200) // findUser.device contains the value
{
for (let i = 0; i < subscriptions.length; i++) { //Notification will be sent to all users which I don't want.
webpush.sendNotification(
subscriptions[i].pushSubscription,
JSON.stringify({
title: "Alert",
content: "Value has reached it's limit",
})
);
}
}
}
});
};
exports.checkStatus=async()=>{
schedule.scheduleJob(“*/10*****”,异步()=>{
let subscriptions=wait Subscription.find({});
让电子邮件=”james@mail.com";
让findUser=wait User.findOne({Email});
if(findUser){
如果(findUser.device>200)//findUser.device包含该值
{
对于(设i=0;i
我如何才能使这项工作,只有那些用户谁的设备的价值已经超过200将只收到通知,而不是所有订阅的用户
exports.checkStatus = async () => {
schedule.scheduleJob("*/10 * * * * *", async () => {
let subscriptions = await Subscription.find({});
let Email = "james@mail.com";
let findUser = await User.findOne({ Email });
if (findUser) {
if (findUser.device > 200) // findUser.device contains the value
{
for (let i = 0; i < subscriptions.length; i++) { //Notification will be sent to all users which I don't want.
webpush.sendNotification(
subscriptions[i].pushSubscription,
JSON.stringify({
title: "Alert",
content: "Value has reached it's limit",
})
);
}
}
}
});
};