Проблема с выполнением асинхронной облачной функции - PullRequest
0 голосов
/ 05 декабря 2018

Моя база данных выглядит следующим образом

enter image description here

Моя облачная функция

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();

exports.userGotNewMessage = functions
.region(`europe-west1`)
.database
.ref(`user-messages/{userId}/{senderId}/{messageId}`)
.onCreate((snap, context) => {
  var userId = context.params.userId
  console.log(`Step 1  ${userId}`)
  var text = snap.val().text
  var toId = snap.val().toId
  var numberOfUnreadMessages = 0
  var db = admin.database()

  if (userId === toId) {
    console.log(`Step 2 ${userId}`)
  var unreadMessagesRef = db.ref(`unread-messages/${userId}`)
  unreadMessagesRef.on("value", (snap) => {
    snap.forEach((childNode) => {
      var nodeNumber = childNode.val().numberOfUnreadMessages
      numberOfUnreadMessages = numberOfUnreadMessages + nodeNumber
    })
    return console.log(`Found ${numberOfUnreadMessages} unread messages for ${userId}`)
  });

  console.log(`Step 3 ${userId}`)
  var token = 'dxfAkmce.....my testing device'
  console.log(text)
  var message = {
    "token": String(token),
    "data": {
      "count": `${numberOfUnreadMessages}`
    }
  }

  admin.messaging().send(message)
  .then((response) => {
    console.log(`Step 4 ${userId}`)
    // Response is a message ID string.
    return console.log('Successfully sent message:', response);
    // detailed information about result if send succeded but something went wrong
    // console.log(response.results[0].error);
  })
  .catch((error) => {
    return console.log('Error sending message:', error);
  });
  }
  console.log(`Step 5 ${userId}`)
  return null
});

При использовании этой функции я получаю странное впечатлениеповедение.Количество непрочитанных сообщений подсчитывается после отправки сообщения и многое другое, например, после запуска я получил сообщение о подсчете непрочитанных сообщений из ниоткуда (в базе данных вообще нет 16 сообщений))) Примерно так в консоли

3: 05: 23.627 PM userGotNewMessage Успешно отправленное сообщение: projects / chatapp-2e320 / messages / 1544015123460374

3: 05: 23.626 PM userGotNewMessage Шаг 4 VobaLy7AKMeYnGv7Og2 * 05: 5 * 7 * 6Q5: 5: 23.340 PM userGotNewMessage Выполнение функции заняло 9 мс, завершено со статусом: 'ok'

3: 05: 23.334 PM userGotNewMessage Шаг 5 nx9XfqgIqyS8PdZ8PzLQ9sEyKoV2

3ZG2P2PX2PXPXF1022 *

3: 05: 23.331 PM userGotNewMessage Начало выполнения функции

3: 05: 23.325 PM userGotNewMessage Выполнение функции заняло 151 мс, завершено со статусом: 'ok'

3: 05: 23.317 PM userGotNewMessage Шаг 5 VobaLy7AKMeYnGv7OgIokaeQ5UG2

3: 05: 23.317 PM userGotNewMessage еще раз

3: 05: 23.317 PM userGotNewMessage Шаг 3 VobaLy7AKMeYnGv7OgIokaeQ5UG2

3: 05: 23.317 PM userGotNewMessage Обнаружено 1 непрочитанных сообщений для VobaLy7342 * 2 * 3OG3GGGEuserGotNewMessage Шаг 2 VobaLy7AKMeYnGv7OgIokaeQ5UG2 * тысяча тридцать-шесть *

3: 05: 23,234 PM userGotNewMessage Шаг 1 VobaLy7AKMeYnGv7OgIokaeQ5UG2 * 1 038 *

3: 05: 23,182 PM userGotNewMessage Найдено 16 непрочитанные сообщения для VobaLy7AKMeYnGv7OgIokaeQ5UG2

3: 05: 23,175PM userGotNewMessage Начало выполнения функции

Я понимаю, что это вызвано асинхронной работой, но я не могу исправить это самостоятельно, потому что я полный новичок.Пожалуйста, помогите мне исправить эти ошибки !!

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Как сказал @rijin в своем ответе, вы должны вернуть обещание, возвращаемое асинхронным методом send().Но, как важно , вы не должны возвращать null в конце функции облака.

Возвращая null, что произойдет до того, как обещания, возвращенные send(), разрешатся, вы указываете облачной функции, что работа завершена.Таким образом, другими словами, облачная функция прекращает выполнение до того, как асинхронное задание будет завершено.

Кроме того, с помощью прослушивателя on() в облачной функции (которая имеет относительно "короткое" значение)жизнь) не совсем адекватна.Вам лучше использовать метод once().

Наконец, вы, очевидно, реализуете две разные части бизнес-логики в своей облачной функции: одну часть для сообщения о количестве непрочитанных сообщений и другую часть для отправки сообщения.Вам следует либо сделать это в двух разных облачных функциях, либо объединить в цепочку разные обещания, возвращаемые асинхронными методами (т. Е. Методы once() и send()).

Итак, для части отправки сообщения должно работать следующее:

exports.userGotNewMessage = functions
.region(`europe-west1`)
.database
.ref(`user-messages/{userId}/{senderId}/{messageId}`)
.onCreate((snap, context) => {
  var userId = context.params.userId
  console.log(`Step 1  ${userId}`)
  var text = snap.val().text
  var toId = snap.val().toId
  var numberOfUnreadMessages = 0
  var db = admin.database()


  console.log(`Step 3 ${userId}`)
  var token = 'dxfAkmce.....my testing device'
  console.log(text)
  var message = {
    "token": String(token),
    "data": {
      "count": `${numberOfUnreadMessages}`
    }
  }

  return admin.messaging().send(message);

});

Если вы хотите объединить методы send() и once() в одной облачной функции, вы можетесделайте что-нибудь по следующим направлениям:

return admin.messaging().send(message)
.then(messageID => {
    if (userId === toId) {
        var unreadMessagesRef = db.ref(`unread-messages/${userId}`);
        return unreadMessagesRef.once('value')
            .then(snap => {
                snap.forEach(childNode => {
                    var nodeNumber = childNode.val().numberOfUnreadMessages;
                    numberOfUnreadMessages = numberOfUnreadMessages + nodeNumber;
                });
                console.log(`Found ${numberOfUnreadMessages} unread messages for ${userId}`);
                return null;
            });
    } else {
        return null;
    }
});
0 голосов
/ 05 декабря 2018

Вы должны вернуть асинхронный ответ.

return admin.messaging().send(message)
  .then((response) => {
    console.log(`Step 4 ${userId}`)
    // Response is a message ID string.
    return console.log('Successfully sent message:', response);
    // detailed information about result if send succeded but something went wrong
    // console.log(response.results[0].error);
  })
  .catch((error) => {
    return console.log('Error sending message:', error);
  });
  }
  console.log(`Step 5 ${userId}`)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...