Node.js - FCM 发送预定主题通知
Posted
技术标签:
【中文标题】Node.js - FCM 发送预定主题通知【英文标题】:Node.js - FCM send scheduled topic notification 【发布时间】:2019-11-06 07:49:05 【问题描述】:我正在使用 Angular 应用程序和 Node.js 服务器通过 FCM 向 android 设备发送主题通知。我正在使用bull 来安排通知。
有两种发送通知的方式:立即发送通知和在特定日期和时间发送通知。
要发送通知,我使用的是 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; )
);
这是我的 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)。“现在”通知
通知正文(从 Angular 发送):
body: "test",
date: undefined,
status: "Notificarea nu a fost trimisă!",
target: "A",
title: "test",
这些是结果和日志:
express deprecated res.send(status): Use res.sendStatus(status) instead routes/notifications.js:41:9
Successfully sent message: messageId: 9203836031271870000
Create new notification
通知到达 Android 应用,一切正常。
2).“预定通知”
通知正文(从 Angular 发送):
body: "test",
date: undefined,
sendDate: "29/06/2019",
sendHour: "07:27",
status: "Notificarea nu a fost programată!",
target: "A",
title: "test",
这些是结果和日志:
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
现在行为有问题。在我重新启动服务器之前,通知不会到达 Android 应用程序。如您所见,它被编程为发送至2019-06-29T04:27:00.000Z
,但即使在较长时间之后也没有发送任何内容。当我重新启动服务器时,Android 应用将收到最后发送的通知。
所以我的问题在于第二种情况:
延迟后不发送通知; 通知似乎没有存储在队列中,所以在我重新启动服务器后只会发送最后一个; 在我重新启动服务器后,之前安排的通知似乎不断发送。例如:发送第一个通知、重启、发送第二个、重启、发送第一个等。我错过了什么?
【问题讨论】:
【参考方案1】:我发现你的代码有两个小问题。
-
作业延迟以秒而不是毫秒为单位发送。
将 delay: Math.abs(jobDelay) );
替换为 delay: Math.abs(jobDelay) * 1e3 );
-
您需要在作业处理完毕后调用 done()。
在sendTopicNotification(job.data.topic, job.data.payload, job.data.options);
之后添加done();
。
【讨论】:
以上是关于Node.js - FCM 发送预定主题通知的主要内容,如果未能解决你的问题,请参考以下文章