Ошибка функции облака Firebase: регистрационные токены, предоставляемые sendToDevice (), должны быть непустой строкой или непустым массивом - PullRequest
0 голосов
/ 04 мая 2019

Я хочу отправить уведомление всем пользователям, которые являются подтвержденными гостями, когда объект подтвержденный гест создан в базе данных Firebase Realtime.

Итак, я сначала создаю массив всех пользователей из объекта подтвержденного гостя. Затем я перебираю всех этих пользователей и помещаю их deviceTokens в массив deviceTokens. Ожидается, что массив allDeviceTokens будет массивом токенов устройств всех пользователей в подтвержденных гостях.

Тем не менее, при создании объекта VerifiedGhest функция возвращает ошибку.

Ниже моя облачная функция


    exports.sendNotification = functions.database
    .ref('/feed/{pushId}/confirmedGuests')
    .onCreate((snapshot, context) => {
        const pushId = context.params.pushId;
        if (!pushId) {
            return console.log('missing mandatory params for sending push.')
        }
        let allDeviceTokens = []
        let guestIds = []
        const payload = {
            notification: {
                title: 'Your request has been confirmed!',
                body: `Tap to open`
            },
            data: {
                taskId: pushId,
                notifType: 'OPEN_DETAILS', // To tell the app what kind of notification this is.
            }
        };
          let confGuestsData = snapshot.val();
          let confGuestItems = Object.keys(confGuestsData).map(function(key) {
              return confGuestsData[key];
          });
          confGuestItems.map(guest => {
            guestIds.push(guest.id)
          })
          for(let i=0; i<guestIds.length; i++){
            let userId = guestIds[i]
            admin.database().ref(`/users/${userId}/deviceTokens`).once('value', (tokenSnapshot) => {
              let userData = tokenSnapshot.val();
              let userItem = Object.keys(userData).map(function(key) {
                  return userData[key];
              });
              userItem.map(item => allDeviceTokens.push(item))
            })
          }
          return admin.messaging().sendToDevice(allDeviceTokens, payload);
    });

1 Ответ

0 голосов
/ 04 мая 2019

Вы загружаете токены устройств каждого пользователя из базы данных реального времени с помощью:

admin.database().ref(`/users/${userId}/deviceTokens`).once('value', (tokenSnapshot) => {

Эта операция загрузки происходит асинхронно.Это означает, что к моменту выполнения вызовов admin.messaging().sendToDevice(allDeviceTokens, payload) токены еще не были загружены.

Чтобы это исправить, вам нужно подождать, пока все токены не загрузятся, прежде чем вызывать sendToDevice().Общий подход для этого заключается в использовании Promise.all()

let promises = [];
for(let i=0; i<guestIds.length; i++){
  let userId = guestIds[i]
  let promise = admin.database().ref(`/users/${userId}/deviceTokens`).once('value', (tokenSnapshot) => {
    let userData = tokenSnapshot.val();
    let userItem = Object.keys(userData).map(function(key) {
      return userData[key];
    });
    userItem.map(item => allDeviceTokens.push(item))
    return true;
  })
  promises.push(promise);
}
return Promise.all(promises).then(() => {
  return admin.messaging().sendToDevice(allDeviceTokens, payload);
})
...