如何编写每小时触发的Firebase函数?Vue.js应用到期任务检测
没问题!我来一步步帮你实现这个Firebase定时任务功能,刚好能满足你每小时检查到期任务并发送通知的需求。下面是具体的步骤和代码示例,你可以根据自己的项目结构调整:
实现Firebase每小时触发的到期任务检查函数
1. 前期准备
首先确保你已经完成了基础的Functions配置:
- 如果还没初始化Firebase Functions,打开终端运行
firebase init functions,选择你熟悉的JavaScript/TypeScript环境,完成初始化。 - 进入functions目录,安装必要依赖:
cd functions && npm install nodemailer(nodemailer用于发送邮件,如果你只需要推送通知可以跳过这步)。
2. 编写定时触发核心函数
Firebase Functions的Pub/Sub触发器支持cron表达式,我们用0 * * * *实现每小时整点触发。同时要注意设置时区,避免触发时间不符合预期。
在functions/index.js(TypeScript对应index.ts)中写入以下代码:
const functions = require("firebase-functions"); const admin = require("firebase-admin"); const nodemailer = require("nodemailer"); // 初始化Firebase Admin SDK admin.initializeApp(); // 配置邮件传输器(以Gmail为例,可替换为SendGrid等其他服务商) const emailTransporter = nodemailer.createTransport({ service: "Gmail", auth: { user: "your-app-email@gmail.com", pass: "your-app-specific-password" // Gmail需开启应用密码,不能用普通账号密码 } }); // 每小时触发的任务检查函数 exports.checkDueTasks = functions.pubsub.schedule('0 * * * *') .timeZone('Asia/Shanghai') // 替换为你所在的时区,比如'UTC' .onRun(async (context) => { const db = admin.database(); const currentTimestamp = Date.now(); try { // 查询所有「已到期且未发送过通知」的任务 const dueTasksSnapshot = await db.ref('/tasks') // 替换为你的任务数据节点路径 .orderByChild('dueTimestamp') .endAt(currentTimestamp) .equalTo(false, 'notified') // 假设任务有notified字段标记是否已通知 .once('value'); if (!dueTasksSnapshot.exists()) { functions.logger.info('本次检查无到期任务'); return null; } // 遍历处理每个到期任务 const dueTasks = dueTasksSnapshot.val(); for (const taskId in dueTasks) { const task = dueTasks[taskId]; const userId = task.userId; // 假设任务关联了用户ID // 获取用户信息(邮箱、FCM推送Token等) const userSnapshot = await db.ref(`/users/${userId}`).once('value'); const user = userSnapshot.val(); if (!user) { functions.logger.warn(`用户${userId}不存在,跳过任务${taskId}`); continue; } // 发送邮件提醒(如果用户有邮箱) if (user.email) { await sendDueTaskEmail(user.email, task.title, task.dueTimestamp); } // 发送FCM推送通知(如果用户有推送Token) if (user.fcmToken) { await sendDueTaskNotification(user.fcmToken, task.title); } // 标记任务为已通知,避免重复处理 await db.ref(`/tasks/${taskId}`).update({ notified: true }); } functions.logger.info('到期任务处理完成'); return null; } catch (error) { functions.logger.error('处理到期任务时出错:', error); throw error; } });
3. 实现邮件与推送通知的辅助函数
在同一个文件中添加以下两个辅助函数:
邮件发送函数
async function sendDueTaskEmail(email, taskTitle, dueTimestamp) { const mailOptions = { from: '你的日程助手 <your-app-email@gmail.com>', to: email, subject: `任务到期提醒:${taskTitle}`, text: `你有一个任务已到期:${taskTitle}\n截止时间:${new Date(dueTimestamp).toLocaleString()}` }; await emailTransporter.sendMail(mailOptions); functions.logger.info(`已发送提醒邮件到${email}`); }
FCM推送通知函数
async function sendDueTaskNotification(fcmToken, taskTitle) { const notificationMessage = { notification: { title: '任务到期提醒', body: `你的任务「${taskTitle}」已经到期了!` }, token: fcmToken }; await admin.messaging().send(notificationMessage); functions.logger.info(`已发送推送通知到Token: ${fcmToken}`); }
4. 关键注意事项
- 数据结构适配:上述代码假设你的数据库结构如下,需根据实际情况调整路径和字段:
- 任务节点:
/tasks/{taskId}包含dueTimestamp(时间戳)、userId、title、notified(布尔值) - 用户节点:
/users/{userId}包含email、fcmToken
- 任务节点:
- 时区设置:一定要在schedule中配置正确的时区,否则触发时间可能和预期不符。
- 权限安全:Firebase Functions使用Admin SDK拥有全数据库访问权限,确保你的数据库规则不会泄露敏感数据。
- 部署函数:完成代码编写后,运行
firebase deploy --only functions即可将函数部署到Firebase。
内容的提问来源于stack exchange,提问作者L. Gangemi
相关产品推荐
相关产品推荐

