Ошибка с регистрационным токеном в FCM с облачными функциями - PullRequest
0 голосов
/ 04 декабря 2018

Я развернул следующий JavaScript в облачной функции Firebase, но постоянно получаю следующую ошибку, хотя знаю, что по указанному пути сохранен токен.

Идея состоит в том, чтобы вызвать уведомление дляУстройство, когда новое сообщение записывается в базу данных, затем извлекает регистрационный токен, который затем используется, чтобы попытаться отправить уведомление пользователю.

enter image description here

Ошибка: регистрационные токены, предоставляемые sendToDevice (), должны быть непустой строкой или непустым массивом.

JS Функция:

exports.notifyNewMessage = functions.database.ref('/messages/{pushId}/{message}').onCreate((snap, context) => {
  const message = snap.val();
  const fromId = message['fromId'];
  const toId = message['toId'];
  const messageTxt = message ['message'];
  const imageUrl = message ['imageUrl'];


  return admin.database().ref('/fcmtokens/' + toId + '/registration-tokens').once('value').then((userTok) => {

    const registrationTokens = userTok.val()

    console.log(registrationTokens);

    return admin.database().ref('/users' + fromId).once('value').then((userDoc) => {

      const senderName = userDoc.firstName //get('firstName')

      const notificationBody = (imageUrl === "") ? "You received a new image message." : messageTxt

        //build media messages notification
        const payload = {
            notification: {
              title: senderName + " sent you a message",
              body: messageTxt
            },
            data: {
              SENDER_NAME: senderName,
              SENDER_ID: fromId

            }//end data
        }//end payload

        //send message
        return admin.messaging().sendToDevice(registrationTokens, payload).then( response => {
          const stillRegisteredTokens = registrationTokens

          response.results.forEach((result, index) => {
                    const error = result.error
                    if (error) {
                        const failedRegistrationToken = registrationTokens[index]
                        console.error('blah', failedRegistrationToken, error)
                        if (error.code === 'messaging/invalid-registration-token'
                            || error.code === 'messaging/registration-token-not-registered') {
                                const failedIndex = stillRegisteredTokens.indexOf(failedRegistrationToken)
                                if (failedIndex > -1) {
                                    stillRegisteredTokens.splice(failedIndex, 1)
                                }
                            }
                    }
                })//end forEach

                return admin.database().ref("fcmtokens/" + recipientId).update({
                    registrationTokens: stillRegisteredTokens
                })//end update

        })//end sendToDevice


    })//end return-then

  })//end return-then

});

Это мой fcmtokens узел структуры базы данных:

"fcmtokens" : {
    "dBQdpR7l1WT2utKVxdX2" : {
      "registration-tokens" : {
        "c4PSCAUAg5s:Yw95DyVxwElE88LwX7" : true
      }
    }
  }

Обновление вопроса: Часть базы данных обновления моей функции, описанной выше, создает отдельную ветвь с именем registrationTokens всех активныхжетоны.Я хочу перезаписать и обновить текущий токен вместо registration-tokens?

return admin.database().ref("fcmtokens/" + recipientId).update({
                        registrationTokens: stillRegisteredTokens
                    })//end update

Изображение, показывающее создание новой ветви registrationTokens.

enter image description here

1 Ответ

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

Учитывая вашу структуру данных, этот код:

admin.database().ref('/fcmtokens/' + toId + '/registration-tokens').once('value').then((userTok) => {
  const registrationTokens = userTok.val()

Приводит к registrationTokens:

{
  "c4PSCAUAg5s:Yw95DyVxwElE88LwX7" : true
}

Затем вы звоните sendToDevice с:

return admin.messaging().sendToDevice(registrationTokens, payload).then( response => {

Но если вы посмотрите справочную документацию для `sendToDevice , там написано:

registrationTokens

Массив строки

Массив регистрационных токенов для устройств, на которые отправляется сообщение.

И, очевидно, ваш registrationTokens не массив, а просто объект.

Чтобы преобразовать его в массив, используйте Object.keys():

  const registrationTokens = Object.keys(userTok.val())
...