当有人喜欢某张照片时,我尝试使用 Firebase Cloud Functions 发送通知。我已经处理了 Firebase 示例,展示了当有人关注您并尝试修改它时如何发送该示例。
问题是,我需要在函数中执行另一个附加查询,以获取喜欢照片的人的 key ,然后才能从用户 Node 获取他们的 token 。问题是 getDeviceTokensPromise 不知何故未实现,并且 tokensSnapshot.hasChildren 无法读取,因为它未定义。我该如何修复它?
exports.sendPhotoLikeNotification = functions.database.ref(`/photo_like_clusters/{photoID}/{likedUserID}`)
.onWrite((change, context) => {
const photoID = context.params.photoID;
const likedUserID = context.params.likedUserID;
// If un-follow we exit the function
if (!change.after.val()) {
return console.log('User ', likedUserID, 'un-liked photo', photoID);
}
var tripName;
var username = change.after.val()
// The snapshot to the user's tokens.
let tokensSnapshot;
// The array containing all the user's tokens.
let tokens;
const photoInfoPromise = admin.database().ref(`/photos/${photoID}`).once('value')
.then(dataSnapshot => {
tripName = dataSnapshot.val().tripName;
key = dataSnapshot.val().ownerKey;
console.log("the key is", key)
return getDeviceTokensPromise = admin.database()
.ref(`/users/${key}/notificationTokens`).once('value');
///// I need to make sure that this returns the promise used in Promise.all()/////
});
return Promise.all([getDeviceTokensPromise, photoInfoPromise]).then(results => {
console.log(results)
tokensSnapshot = results[0];
// Check if there are any device tokens.
//////This is where I get the error that tokensSnapshot is undefined///////
if (!tokensSnapshot.hasChildren()) {
return console.log('There are no notification tokens to send to.');
}
// Notification details.
const payload = {
notification: {
title: 'Someone liked a photo!',
body: `${username} liked one of your photos in ${tripName}.`,
}
};
// Listing all tokens as an array.
tokens = Object.keys(tokensSnapshot.val());
// Send notifications to all tokens.
return admin.messaging().sendToDevice(tokens, payload);
});
最佳答案
好的,根据您的评论,这是更新的答案。
您需要链接您的 Promise,并且不需要使用 Promise.all()
- 该函数用于异步任务的集合,所有这些任务都需要在您采取下一个操作之前完成(并行)。
您的解决方案应如下所示:
admin.database().ref(`/photos/${photoID}`).once('value')
.then(dataSnapshot => {
// Extract your data here
const key = dataSnapshot.val().ownerKey;
// Do your other stuff here
// Now perform your next query
return admin.database().ref(`/users/${key}/notificationTokens`).once('value');
})
.then(tokenSnapshot => {
// Here you can use token Snapshot
})
.catch(error => {
console.log(error);
});
由于您的第二个网络请求取决于第一个网络请求的完成,因此请通过在第一个网络请求之后附加第二个 .then()
来链接您的 promise ,并且不要用分号 ; 终止它。如果在第一个 .then()
范围内创建的新 Promise 解析,它将调用第二个 .then()
函数。
如果您需要在第二个作用域中访问第一个 .then()
作用域中的变量,则必须在通用函数中声明它们,并在闭包作用域中分配它们。
您可以查看 promise chaining here 的更多信息。
关于javascript - 如何在正确的范围内做出 Promise,以便它具有要查询的正确值并返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50776237/