[英]Node.js - FCM send scheduled topic notification
I'm using an Angular app and a Node.js server to send topic notifications to Android devices using FCM. 我正在使用Angular应用程序和Node.js服务器使用FCM向Android设备发送主题通知。 I am using bull to schedule the notifications.
我正在使用公牛来安排通知。
There are two ways of sending a notification: send a notification now and send a notification at a specific date and time. 发送通知有两种方式:立即发送通知并在特定日期和时间发送通知。
To send notifications I am using an Angular app and this method: 要发送通知我正在使用Angular应用程序和此方法:
sendTopicNotification(notification: Notification): Observable<any> {
console.log("send topic");
return this.http.post(endpoint + `notifications/send/topic/topic${notification.target}`, JSON.stringify(notification), httpOptions).pipe(
map(result => { return true; })
);
}
This is my Node.js code: 这是我的Node.js代码:
const express = require('express');
const router = express.Router();
const fb = require('../firebase/fb');
const db = fb.firestore();
const fcm = fb.messaging();
const moment = require('moment');
var Queue = require('bull');
var notificationsQueue = new Queue('topic notifications', { redis: { port: 6379, host: '127.0.0.1' } }); // Specify Redis connection using object
const notificationsCollection = 'notifications';
const donationsCollection = 'donations';
router.post('/send/topic/:topic', (req, res) => {
var topic = `/topics/${req.params.topic.toString()}`;
var payload = {
notification: {
title: req.body.title,
body: req.body.body
}
};
var options = {
priority: "high",
timeToLive: 60 * 60 * 24
};
if (req.body.sendDate && req.body.sendHour) {
var date = req.body.sendDate;
var hour = req.body.sendHour;
scheduleMessage(date, hour, topic, payload, options);
} else {
sendTopicNotification(topic, payload, options);
}
res.send(200);
});
//Schedule the job
async function scheduleMessage(date, hour, topic, payload, options, res) {
var date = date.toString().split("/");
var hour = hour.toString().split(":");
console.log(date[2], date[1], date[0], hour[0], hour[1], 0);
var jobDate = new Date(date[2], date[1] - 1, date[0], hour[0], hour[1]);
console.log(jobDate);
console.log(new Date());
var jobDelay = ((jobDate.getTime() / 1000) - (Math.floor(new Date().getTime() / 1000)));
console.log(jobDate.getTime() / 1000);
console.log(Math.abs(jobDelay));
console.log(Math.floor(new Date().getTime() / 1000));
const job = await notificationsQueue.add({
topic: topic,
payload: payload,
options: options
}, { delay: Math.abs(jobDelay) });
console.log(date + " " + hour);
}
//Process qued job
notificationsQueue.process(async (job, done) => {
console.log(job.data);
sendTopicNotification(job.data.topic, job.data.payload, job.data.options);
});
//Send notificaiton
function sendTopicNotification(topic, payload, options) {
var currentTime = new Date().getTime();
var target;
switch (topic) {
case "/topics/topicA":
target = 'Donatorii cu grupa sanguină A'
break;
case "/topics/topicB":
target = 'Donatorii cu grupa sanguină B'
break;
case "/topics/topicAB":
target = 'Donatorii cu grupa sanguină AB'
break;
case "/topics/topic0":
target = 'Donatorii cu grupa sanguină 0'
break;
case "/topics/topicAll":
target = 'Toți donatorii'
break;
default:
break;
}
fcm.sendToTopic(topic, payload, options)
.then((response) => {
db.collection(notificationsCollection).doc(currentTime.toString()).set({
title: payload.notification.title,
body: payload.notification.body,
date: currentTime,
target: target,
status: "Notificarea a fost trimisă!"
}).then((res) => {
console.log('Create new notification ');
});
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
db.collection(notificationsCollection).doc(currentTime.toString()).set({
title: payload.notification.title,
body: payload.notification.body,
date: currentTime,
target: topic,
status: "Notificarea nu a fost trimisă!"
}).then(() => {
console.log('Create new notification');
});
console.log('Error sending message:', error);
});
}
module.exports = router;
1). 1)。 "Now" notification
“现在”通知
Notification body (sent from Angular): 通知机构(从Angular发送):
{
body: "test",
date: undefined,
status: "Notificarea nu a fost trimisă!",
target: "A",
title: "test",
}
These are the result and the logs: 这些是结果和日志:
express deprecated res.send(status): Use res.sendStatus(status) instead routes/notifications.js:41:9
Successfully sent message: { messageId: 9203836031271870000 }
Create new notification
The notification reaches the Android app and everything works normal as expected. 通知到达Android应用程序,一切正常,如预期。
2). 2)。 "Scheduled notification"
“预定通知”
Notification body (sent from Angular): 通知机构(从Angular发送):
{
body: "test",
date: undefined,
sendDate: "29/06/2019",
sendHour: "07:27",
status: "Notificarea nu a fost programată!",
target: "A",
title: "test",
}
These are the result and the logs: 这些是结果和日志:
2019-06-29T04:27:00.000Z
2019-06-29T04:25:35.070Z
{ topic: '/topics/topicA',
payload: { notification: { title: 'test', body: 'test' } },
options: { priority: 'high', timeToLive: 86400 } }
Successfully sent message: { messageId: 5284791767401410000 }
Create new notification
Now there is something wrong with the behaviour. 现在这个行为有问题了。 The notification won't reach the Android app until I restart the server.
在重新启动服务器之前,通知将无法访问Android应用。 As you can see it is programmed to be sent at
2019-06-29T04:27:00.000Z
, but nothing was sent even after a longer period. 如您所见,它被编程为在
2019-06-29T04:27:00.000Z
发送,但即使经过较长时间后也没有发送任何内容。 When I restart the server the Android app will receive the last sent notification. 当我重新启动服务器时,Android应用程序将收到最后发送的通知。
So my problems are in the second scenario: 所以我的问题出现在第二种情况中:
What am I missing? 我错过了什么?
I see two small problems with your code. 我看到你的代码有两个小问题。
Replace { delay: Math.abs(jobDelay) });
替换
{ delay: Math.abs(jobDelay) });
with { delay: Math.abs(jobDelay) * 1e3 });
{ delay: Math.abs(jobDelay) * 1e3 });
Add done();
添加
done();
after sendTopicNotification(job.data.topic, job.data.payload, job.data.options);
在
sendTopicNotification(job.data.topic, job.data.payload, job.data.options);
之后sendTopicNotification(job.data.topic, job.data.payload, job.data.options);
. 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.