Как я могу сделать Обещание в правильной области, чтобы оно содержало правильные значения для запроса, а также возвращало? - PullRequest
0 голосов
/ 09 июня 2018

Я пытаюсь отправить уведомление с помощью 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);
      });

1 Ответ

0 голосов
/ 09 июня 2018

Хорошо, поэтому, основываясь на вашем комментарии, вот обновленный ответ.

Вам нужно связать свои обещания, и вам не нужно использовать 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(), разрешится, оно вызовет вторую функцию .then().

Если вам необходимо получить доступ к переменным из первой области .then() во второй, то вы должны объявить их в общей функции и назначить их в области замыкания.

Более подробную информацию о цепочке обещаний вы можете посмотреть здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...