具有云功能的FCM中的注册令牌错误 [英] Error with registration token in FCM with Cloud Functions

查看:79
本文介绍了具有云功能的FCM中的注册令牌错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将以下JavaScript部署到Firebase Cloud Function中,但是即使我知道在指定的路径下保存了令牌,也会不断出现以下错误.

I have deployed the following JavaScript to Firebase Cloud Function but I am constantly getting the following error even though I know that there is a token saved under the path specified.

这个想法是在将新消息写入数据库时​​触发向设备的通知,然后它获取注册令牌,然后将其用于尝试向用户发送通知.

The idea is to trigger a notification to device when a new message is written to the database, it then fetches the registration token which is then used to try and send a notification to the user.

错误:提供给sendToDevice()的注册令牌必须是非空字符串或非空数组.

Error: Registration token(s) provided to sendToDevice() must be a non-empty string or a non-empty array.

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 数据库结构节点:

This is my fcmtokens database structure node:

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

问题更新:我上面函数的更新数据库部分是为所有活动令牌创建一个名为 registrationTokens 的单独分支.我想改写并更新 registration-tokens 下的当前令牌吗?

Question update: The update database part of my function above is creating a separate branch called registrationTokens of all active tokens. I want to overwrite and update the current token under registration-tokens instead?

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

图片显示了正在创建的新 registrationTokens 分支.

Image showing the new registrationTokens branch being created.

推荐答案

给出您的数据结构,此代码:

Given your data structure, this code:

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

registrationTokens 的线索为:

{
  "c4PSCAUAg5s:Yw95DyVxwElE88LwX7" : true
}

然后您通过以下方式调用 sendToDevice :

You then call sendToDevice with:

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

但是,如果您查看参考文档,`sendToDevice ,它说:

But if you look at the reference documentation for `sendToDevice, it says:

注册令牌

字符串数组

用于向其发送消息的设备的注册令牌的数组.

An array of registration tokens for the devices to which to send the message.

很显然,您的 registrationTokens 不是数组,而只是对象.

And clearly your registrationTokens is not an array, but just an object.

要将其转换为数组,请使用 Object.keys() :

To convert it to an array use Object.keys():

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

这篇关于具有云功能的FCM中的注册令牌错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆