Firebase 在云函数返回之前,如何正确地从实时数据库获取用户配置文件以获取他们的用户名?
我正在实现云功能,以便在有趣的事情发生时(如跟踪、喜欢、评论)向用户发送通知。我复制并改编了Firebase教程,以便在检测到关注者节点的更改时发送通知,但我还需要查询数据库以获取关注者的帐户数据,包括他们的用户名。我想我已经很接近了,但是函数没有及时完成,我很难理解承诺。以下是函数:Firebase 在云函数返回之前,如何正确地从实时数据库获取用户配置文件以获取他们的用户名?,firebase,firebase-realtime-database,google-cloud-functions,Firebase,Firebase Realtime Database,Google Cloud Functions,我正在实现云功能,以便在有趣的事情发生时(如跟踪、喜欢、评论)向用户发送通知。我复制并改编了Firebase教程,以便在检测到关注者节点的更改时发送通知,但我还需要查询数据库以获取关注者的帐户数据,包括他们的用户名。我想我已经很接近了,但是函数没有及时完成,我很难理解承诺。以下是函数: exports.sendFollowerNotification = functions.database.ref(`/userFollowers/{followedUid}/{followerUid}`
exports.sendFollowerNotification = functions.database.ref(`/userFollowers/{followedUid}/{followerUid}`)
.onWrite((change, context) => {
const followerUid = context.params.followerUid;
const followedUid = context.params.followedUid;
// If un-follow we exit the function
if (!change.after.val()) {
return console.log('User ', followerUid, 'un-followed user', followedUid);
}
console.log('We have a new follower UID:', followerUid, 'for user:', followedUid);
// Get the list of device notification tokens.
const getDeviceTokensPromise = admin.database()
.ref(`/users/${followedUid}/notificationTokens`).once('value');
console.log('Found the followed user\'s token')
const userInfo = admin.database().ref(`/users/${followedUid}`).once('value');
console.log(userInfo)
const username = userInfo['username'];
console.log(username);
////////////////// ABOVE is where I'm trying to get the username by reading their account data ///////////////////
// Get the follower profile.
const getFollowerProfilePromise = admin.auth().getUser(followerUid);
// The snapshot to the user's tokens.
let tokensSnapshot;
// The array containing all the user's tokens.
let tokens;
return Promise.all([getDeviceTokensPromise, getFollowerProfilePromise]).then(results => {
tokensSnapshot = results[0];
const follower = results[1];
// Check if there are any device tokens.
if (!tokensSnapshot.hasChildren()) {
return console.log('There are no notification tokens to send to.');
}
console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.');
console.log('Fetched follower profile', follower);
// Notification details.
const payload = {
notification: {
title: 'You have a new follower!',
body: `{username} is now following you.`,
}
};
// Listing all tokens as an array.
tokens = Object.keys(tokensSnapshot.val());
// Send notifications to all tokens.
return admin.messaging().sendToDevice(tokens, payload);
}).then((response) => {
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
console.error('Failure sending notification to', tokens[index], error);
// Cleanup the tokens who are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
}
}
});
return Promise.all(tokensToRemove);
});
});
如何确保用户名在返回之前可用?谢谢。好的,我想我明白你的意思了 这些代码行不符合您的想法。所有数据库读取都是异步完成的,因此
const userInfo = admin.database().ref(`/users/${followedUid}`).once('value');
console.log(userInfo)
const username = userInfo['username'];
console.log(username);
,因此,userInfo
实际上是一种返回数据的承诺。在执行之后的操作之前,您将无法获取数据
我担心会有更多的连锁承诺。。。只需将userInfo
重命名为userInfoPromise
,并将其添加到您的承诺中。所有数组。好的,我想我明白您的意思了
这些代码行不符合您的想法。所有数据库读取都是异步完成的,因此
const userInfo = admin.database().ref(`/users/${followedUid}`).once('value');
console.log(userInfo)
const username = userInfo['username'];
console.log(username);
,因此,userInfo
实际上是一种返回数据的承诺。在执行之后的操作之前,您将无法获取数据
我担心会有更多的连锁承诺。。。只需将userInfo
重命名为userInfoPromise
,并将其添加到您的Promise.All
数组中。好吧,在云函数返回之前,您不需要做任何事情。这里有一个有趣的功能视频。基本上,您正在将一个函数传递到promise中,以便在检索datasnapshot时执行。在运行您发送的代码之前,All将等待所有承诺完成。这都是异步的。考虑到这一点,看起来您正在尝试编排大量代码来完成。也许有一种更好的方法来构造调用/DB,以避免大部分调用?自由层具有合理的执行限制。有一些很棒的视频。也许可以通过观看视频来了解如何展平你的身体DB@JamesPoag这段视频有助于我的理解。不过,该功能是直接从Firebase复制而来的——我确信它的设计有点过度,尤其是在日志记录方面。我也是付费的!你在付费层,而它正在超时?天哪,那就像是几秒钟?也许这不是超时?这不是超时!读取/user/uid值不会在函数的其余部分之前返回,因此用户名永远不可用。我试图理解如何确保它在函数的其余部分之前返回,从而使其可用。好吧,在云函数返回之前,您实际上不需要做任何事情。这里有一个有趣的功能视频。基本上,您正在将一个函数传递到promise中,以便在检索datasnapshot时执行。在运行您发送的代码之前,All将等待所有承诺完成。这都是异步的。考虑到这一点,看起来您正在尝试编排大量代码来完成。也许有一种更好的方法来构造调用/DB,以避免大部分调用?自由层具有合理的执行限制。有一些很棒的视频。也许可以通过观看视频来了解如何展平你的身体DB@JamesPoag这段视频有助于我的理解。不过,该功能是直接从Firebase复制而来的——我确信它的设计有点过度,尤其是在日志记录方面。我也是付费的!你在付费层,而它正在超时?天哪,那就像是几秒钟?也许这不是超时?这不是超时!读取/user/uid值不会在函数的其余部分之前返回,因此用户名永远不可用。我试图理解如何确保它在函数的其余部分之前返回,从而使它可用。