如何在 Firebase 控制台之外发出预定的 Firebase 云消息传递通知?

How can scheduled Firebase Cloud Messaging notifications be made outside of the Firebase Console?

在 Firebase 控制台的云消息视图下,用户可以创建测试通知。此功能还允许您安排将通知发送到一个或一组设备的时间。

是否可以使用 firebase 云功能和 Firebase Admin SDK 创建并向特定设备发送 预定 FCM 通知?有解决此问题的替代方法吗?

我目前给用户发送定时消息的方式是这样的:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const schedule = require('node-schedule');
admin.initializeApp();

exports.setScheduledNotification = functions.https.onRequest(async (req, res) => {
    const key = req.query.notification_key;

    const message = {
        notification: {
            title: 'Test Notification',
            body: 'Test Notification body.'
        }
    };

    var currentDate = new Date();
    var laterDate = new Date(currentDate.getTime() + (1 * 60000));

    var job = schedule.scheduleJob(key, laterDate, () => {
        const snapshot = admin.messaging().sendToDevice(key, message);
    });

    return res.status(200).send(`Message has been scheduled.`);
});

首先,我不确定 node-schedule 如何与 firebase 云函数交互。日志显示该函数终止得非常快,我认为这是正确的。操作时间越长 运行s,我们的 firebase 账单成本就越高。不过,通知仍然会在预定时间 运行。我对这一切在幕后的运作方式感到困惑。

其次,我在取消这些预定通知时遇到了问题。通知很可能从创建之日起按 2 小时的定时时间表进行。在 2 小时结束之前,我希望能够 cancel/overwrite 更新预定时间的通知。

我试过取消通知,但找不到之前创建的通知。这是相关代码:

exports.cancelScheduledNotification = functions.https.onRequest(async (req, res) => {
    const key = req.query.notification_key;

    var job = schedule.scheduledJobs[key];
    job.cancel();

    return res.status(200).send(`Message has been canceled.`);
});

是否可以在 firebase 控制台之外利用 firebase 云消息传递的调度功能?还是我一直在用黑客手段解决这个问题?

云函数可以 运行 最多 9 分钟。因此,除非您使用 node-schedule 的时间短于此,否则您当前的方法将行不通。即使它可行,或者如果您 提前安排不到 9 分钟,使用这种方法是非常不经济的,因为您将一直为 Cloud Functions 付费,同时正在等待。


一种更常见的方法是将有关您希望在什么时间将什么消息传递给谁的信息存储在数据库中,然后使用定期计划函数定期检查要发送的消息。有关这方面的更多信息,请参阅之前的这些问题:

  • Firebase scheduled notification in android
  • How to schedule push notifcations for react native expo?
  • How to create cron jobs dynamically in firebase

最近对此的改进是使用 Cloud Tasks API 以编程方式安排 Cloud Functions 在特定时间使用特定负载调用,然后使用它通过 FCM 发送消息。 Doug Stevenson 在此处写了一篇很棒的博客 post:How to schedule a Cloud Function to run in the future with Cloud Tasks (to build a Firestore document TTL)。虽然 post 是关于在特定时间删除文档,但您也可以将其与之前的方法结合使用以安排 FCM 消息。


最后一件事要注意:虽然 Firebase Cloud Messaging 会在应用程序未激活时自动处理 notification 消息的显示,但您也可以仅将其用于传递部分使用 data 消息,然后在您的应用程序代码中处理所有显示。如果您使用该方法,您可以立即发送 FCM data 消息以及显示消息的时间,然后唤醒设备 display 当时留言