我正在使用单个firebase功能向我的Android用户发送多个推送通知。
每个通知的详细信息都会在我们的Firebase数据库中写下它们应发送的日期和小时。我使用cron通过http请求触发此Firebase函数。
我的问题是Firebase功能返回应该是什么才能完成所有Firebase节点的循环(代表通知)并完成发送所有通知?
这就是我现在所拥有的。它在发送第一个通知后退出。我想要的是它完成所有Firebase子节点的查看并为每个节点发送通知。
我不明白Promises的想法足以弄清楚在多个Push Notifications的情况下返回什么。我几乎完全忘记了如何编写javascript也无济于事。
exports.sendHourlyNotifications = functions.https.onRequest((req, res) => {
const dateStr = req.query.date;
const hourStr = req.query.hour;
console.log('sendHourlyNotifications', 'date: ' + dateStr + " hour: " + hourStr);
const parentRef = admin.database().ref();
const notifRef = parentRef.child('all-notifications');
const hourRef = notifRef.child(dateStr).child(hourStr);
return hourRef.once('value').then(snapshot => {
const updates = {};
snapshot.forEach(function(childSnapshot) {
const deviceToken = childSnapshot.child("deviceToken").val();
console.log('sendHourlyNotifications', 'childSnapshot Key: ' + childSnapshot.key);
const title = childSnapshot.child("title").val();
const body = childSnapshot.child("body").val();
console.log('sendHourlyNotifications', "DeviceToken: " + deviceToken + " Title: " + title + " Body: " + body);
var payload = {
notification: {
title: title,
body: body,
}
};
admin.messaging().sendToDevice(deviceToken, payload);
return Promise.all([
/* ... */
]).then(() => {
res.status(200).send('ok');
}).catch(err => {
console.log(err.stack);
res.status(500).send('error');
});
});
return parentRef.update(updates);
});
});
如果无法在同一个Firebase功能执行中发送多个推送通知,那么我想我将不得不重新架构一下。如果是这种情况,我欢迎任何提示或示例链接到更好的设计。
答案 0 :(得分:5)
由于此功能是由HTTP请求触发的,因此您无需从顶级功能返回任何内容。一旦您致电send
,该功能即被视为已完成。
因此,您需要做的是重构代码,在您发送所有通知后才调用send()
:
return hourRef.once('value').then(snapshot => {
var promises = [];
snapshot.forEach(function(childSnapshot) {
const deviceToken = childSnapshot.child("deviceToken").val();
const title = childSnapshot.child("title").val();
const body = childSnapshot.child("body").val();
var payload = {
notification: {
title: title,
body: body,
}
};
promises.push(admin.messaging().sendToDevice(deviceToken, payload));
});
// The res.send() needs to be outside of the snapshot.forEach() callback
Promise.all(promises).then(() => {
res.status(200).send('ok');
}).catch(err => {
console.log(err.stack);
res.status(500).send('error');
});
});
如果你是"新"对于JavaScript,Firebase的云功能并不是学习它的最佳方式。我建议先阅读Firebase documentation for Web developers和/或Firebase codelab for Web developer。它们涵盖了许多基本的JavaScript,Web和Firebase交互。您还可以在本地Node.js进程中使用Admin SDK,该进程可以使用本地调试器进行调试。在那些之后,您也可以更好地为云功能编写代码。