首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我如何才能在正确的作用域中做出承诺,使其具有正确的值来进行查询并返回?

我如何才能在正确的作用域中做出承诺,使其具有正确的值来进行查询并返回?
EN

Stack Overflow用户
提问于 2018-06-10 00:18:06
回答 1查看 73关注 0票数 1

当有人喜欢一张照片时,我正在尝试使用Firebase Cloud Functions发送通知。我已经解决了Firebase的例子,展示了当有人关注你并试图修改它时如何发送一个。

问题是,我需要在函数中执行另一个额外的查询,以获得喜欢照片的人的密钥,然后才能从他们的用户节点获得他们的令牌。问题是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);
      });
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-10 02:32:59

好的,根据你的评论,这是最新的答案。

您需要链接您的承诺,并且您不需要使用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()来链接您的承诺,并且不要使用分号;终止它。如果在第一个.then()作用域中创建的新promise解析,它将调用第二个.then()函数。

如果您需要访问第二个.then()作用域中的变量,则必须在常规函数中声明它们,并在闭包作用域中分配它们。

你可以在promise chaining here上查看更多信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50776237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档