Firebase функции для цикла асинхронного ожидания - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь сделать относительно простую, теоретически функцию с использованием Firebase Functions.

В частности:

  • Добавить + 1 в переменную базы данных в реальном времени для всех пользователей

  • Отправить уведомление всем пользователям

Я все еще пытаюсь понять async / await, поэтому, возможно, поэтому я так борюсь с этим.

Вот что я делаю:

 exports.gcIncrement = functions.database
  .ref('gthreads/{threadId}/messages/{messageId}')
  .onCreate(async (snapshot, context) => {

    const data = snapshot.val();
    const threadId = context.params.threadId;
    const uid = context.auth.uid;

    adb.ref('gchats/' + threadId).once('value').then(async (gchatData) => {
    const parent = gchatData.val();
    incrementUser(parent.users, uid, threadId); //parent.users is an object with 1-30 users.
    sendGCNotification(parent.users, data);
    return true;
  }).catch(error => console.log(error))
});

И тогда у меня есть функция incrementUser:

function IncrementUser(array, uid, threadId) {
    for (const key in array) {
      if (key != uid) {
        const gcMessageRef =
        adb.ref('users/' + key + '/gthreads/' + threadId + '/' + threadId+'/unread/');
        gcMessageRef.transaction((int) => {
          return (int || 0) + 1;
      }
    }
  }

и функция sendGCNotification:

  function sendGCNotification(array, numbOfMsg, data) {
    let payload = {
      notification: {
        title: 'My App - ' + data.title,
        body: "This is a new notification!",
      }
    }
    const db = admin.firestore()
    for (const key in array) {
      if (!data.adminMessage) {
        if (array[key] === 0) {

          const devicesRef = db.collection('devices').where('userId', '==', key)

          const devices = await devicesRef.get();
          devices.forEach(result => {
            const tokens = [];
            const token = result.data().token;
            tokens.push(token)

            return admin.messaging().sendToDevice(tokens, payload)
          })

        }
      }
    }
  }

Я сейчас получаю сообщение об ошибке:

Выражение 'await' разрешено только внутри асинхронной функции.

const devices = await devicesRef.get ();

Но даже когда я получаю это без ошибок, это не похоже на работу. Журнал Firebase Functions сообщает:

16:45:26.207 gcIncrement Выполнение функции заняло 444 мс, завершено со статусом «ок» 16:45:25.763 gcIncrement Начало выполнения функции

Так что, похоже, он работает как ожидалось, но не выполняет код, как ожидалось. Есть идеи? Спасибо!

1 Ответ

0 голосов
/ 08 января 2019

Все случаи использования await должны происходить в основном теле функции, помеченной async. Ваша функция sendGCNotification не является асинхронной. Вам нужно будет пометить его как асинхронный, а также убедиться, что все обещания в нем ожидаются, или вернуть обещание, которое разрешается после выполнения всей асинхронной работы.

Кроме того, в IncrementUser вы не обрабатываете обещание, возвращаемое gcMessageRef.transaction (). Вам необходимо обработать каждое обещание, которое вы генерируете из всей асинхронной работы, и убедиться, что все они являются частью окончательного обещания, которое вы возвращаете или ожидаете от своей функции верхнего уровня.

Если вы хотите узнать больше об обещаниях и асинхронности / ожидании в коде Cloud Functions, я предлагаю вам использовать мои видеоряд . В частности, под названием «Как асинхронное / ожидание работает с TypeScript и ECMAScript 2017?». Даже если вы не используете TypeScript, async / await работает так же.

...