【发布时间】:2021-06-28 00:36:32
【问题描述】:
我不熟悉通过 http 触发函数为 Firebase 使用云函数,我对如何正确终止该函数感到困惑。我不确定我是否应该使用 res.sendStatus、返回一个 Promise 或两者兼而有之。
我的函数的目标是遍历集合“社区”中的多个文档。每个社区都有一个文档集合,我在其中查询具有最高值'hotScore'的文档。然后,我将包含该文档的 iOS 推送通知发送到某个主题(给定社区中的所有用户)。
不幸的是,我在运行代码时遇到了几个错误,例如Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client 和Unhandled rejection。我很可能这是由于我在处理函数终止时的疏忽,尽管到目前为止我一直对我所看到的在线资源感到困惑。有人介意看看我的代码/指出我正确的方向吗?非常感谢!
exports.sendNotificationTrendingPost = functions.https.onRequest(async (req, res) => {
//Get communities collection from Firestore
return admin.firestore().collection('communities').get().then((communities) => {
var communityPromises = [];
//Loop through each community
communities.forEach((community) => {
let communityID = community.get('communityID');
let communityName = community.get('name');
//Get the post with the highest hotScore
let communityPromise = admin.firestore().collection('communities').doc(communityID).collection('posts').orderBy('hotScore', 'desc').limit(1).get().then((posts) => {
let hottestPost = posts[0];
let postID = hottestPost.get('postID');
let postText = hottestPost.get('text');
let currentDate = Date.now() / 1000;
var message;
//Verify that the hottest post was posted in the past 24 hours
if (hottestPost.get('date') > (currentDate - 86400)) {
//Build the notification text (shortening if too long)
let shortenedPostText = postText.substring(0,60);
var textEnd = '';
if (postText.length > 60) {
textEnd = '...';
}
let notificationText = 'Trending post on ' + communityName + ': ' + shortenedPostText + textEnd;
//Build the push notification
message = {
apns: {
headers: {
'apns-push-type': 'alert'
},
payload: {
aps: {
alert: {
body: notificationText,
},
},
postID: postID,
},
},
topic: communityID
}
}
//Send the message and return the promise
if (message === null) {
return null;
} else {
return admin.messaging().send(message);
}
})
.catch(error => {
console.log(error);
res.status(500).send(error);
})
if (communityPromise !== null) {
communityPromises.push(communityPromise);
}
})
res.sendStatus(200);
return Promise.all(communityPromises);
})
.catch(error => {
console.log(error);
res.status(500).send(error);
})
})
【问题讨论】:
-
我稍后会回到这个,但应该注意的是,为 HTTP 请求函数返回
Promise没有任何作用。乍一看,您拨打res.status(500).send(error),然后拨打res.sendStatus(200)。我会考虑重构您的代码以在此处使用async/await语法,因为您已经进入了嵌套承诺领域,这会让您发现这样的事情。
标签: node.js firebase google-cloud-functions firebase-cloud-messaging