代码之家  ›  专栏  ›  技术社区  ›  Cody Lucas

在云函数返回之前,如何正确地从实时数据库获取用户配置文件以获取其用户名?

  •  0
  • Cody Lucas  · 技术社区  · 7 年前

    我正在实现云功能,以便在有意思的事情发生时(如跟踪、喜欢、评论)向我的用户发送通知。我复制并修改了FireBase教程,以便在检测到关注者节点的更改时发送通知,但我还需要查询数据库以获取关注者的帐户数据,包括他们的用户名。我觉得我很接近,但是这个功能没有及时完成,我很难理解承诺。功能如下:

        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);
              });
            });
    

    如何确保用户名在返回前可用?谢谢。

    1 回复  |  直到 7 年前
        1
  •  2
  •   James Poag    7 年前

    好吧,我想我明白你的意思了…

    这些代码行并不像你想的那样。所有数据库读取都是异步的,所以…

    const userInfo = admin.database().ref(`/users/${followedUid}`).once('value');
    console.log(userInfo)
    const username = userInfo['username'];
    console.log(username);
    

    once returns a promise ,所以 userInfo 实际上是承诺返回数据。除非你做了一个 then .

    恐怕还有更多的连锁承诺…只需重命名 用户信息 userInfoPromise 把它加到你的 Promise.All 数组。