首页 > 解决方案 > CanonicalRegistrationTokenCount 的 Firebase 云函数错误

问题描述

我正在尝试在注册后向我的应用发送注册通知,并且用户已保存在数据库中。为此,我正在使用 firebase 云功能。

我已经从 firebaseinstanceidservice 获取了设备令牌,并将其保存在用户的数据库中,users/userid/deviceToken并在函数中引用了该路径,如下面的代码:

exports.sendNotification = functions.database.ref("users/{userId}/{instanceId_token}")

我已经尝试记录 devicetoken 以确保但在云控制台中,我不断获取该日志的其他属性,例如 : sendNotification deviceToken namesendNotification deviceToken userId而不是保存在 db 中的字母数字值。这条路错了吗?

这是我的完整代码:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.sendNotification = 
functions.database.ref("users/{userId}/{instanceId_token}")
    .onWrite((changes, context) => {
    const userId = context.params.userId;
    console.log("user-id", userId);
    const notificationToken = context.params.instanceId_token;
    console.log("deviceToken", notificationToken);

    var payload = {
      data: {
          title: "Welcome to My Group",
          message: "You may have new messages"
      }
    };
  return admin.messaging().sendToDevice(notificationToken, payload)
      .then(function (response) {
          return console.log("Successfully sent message: ", response);
      })
      .catch(function (error) {
         return console.log("Error sending message: ", error);
      })
  });

此外,该函数在admin.messaging回调之后显示了这个温和的积极消息:

Successfully sent message:  { results: [ { error: [Object] } ],
   canonicalRegistrationTokenCount: 0,
   failureCount: 1,
   successCount: 0,
   multicastId: 8880906162831350000 }

我如何解决这个问题,我使用的是安卓客户端?

这是我的数据库结构: 在此处输入图像描述

标签: firebasegoogle-cloud-functions

解决方案


您应该在上层节点上触发您的功能,如下所示。并instanceId_token通过changes.after.val().

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.sendNotification = 
functions.database.ref("users/{userId}")
    .onWrite((changes, context) => {
    const userId = context.params.userId;
    console.log("user-id", userId);
    const notificationToken = changes.after.val().instanceId_token;
    console.log("deviceToken", notificationToken);



    var payload = {
      data: {
          title: "Welcome to My Group",
          message: "You may have new messages"
      }
    };

  return admin.messaging().sendToDevice(notificationToken, payload)
      .catch(function (error) {
         console.log("Error sending message: ", error);
      })
  });

如果您在instanceId_token创建用户后添加 ONLY ,那么您应该触发onUpdate()(“在数据更新时触发”,而onWrite()“在创建、更新或删除数据时触发”)。

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.sendNotification = 
functions.database.ref("users/{userId}")
    .onUpdate((changes, context) => {
    const userId = context.params.userId;
    console.log("user-id", userId);
    const notificationToken = changes.after.val().instanceId_token;
    console.log("deviceToken", notificationToken);

    if (notificationToken === undefined) {
        console.log("notificationToken === undefined");
      return false;
    } else {

       var payload = {
          data: {
             title: "Welcome to My Group",
             message: "You may have new messages"
         }
       };
      return admin.messaging().sendToDevice(notificationToken, payload)
         .catch(function (error) {
             console.log("Error sending message: ", error);
         })    
       }
  });

另请注意,您不应该这样做

  return admin.messaging().sendToDevice(notificationToken, payload)
      .then(function (response) {
          return console.log("Successfully sent message: ", response);
      })
      .catch(function (error) {
         return console.log("Error sending message: ", error);
      });

因为在这种情况下,您不会返回“在函数中完成所有异步工作时解决”的承诺。(见这个问题的答案)

因此,只需返回 sendToDevice 返回的承诺(请参阅doc),如下所示:

  return admin.messaging().sendToDevice(notificationToken, payload)
      .catch(function (error) {
         console.log("Error sending message: ", error);  // here no return
      });

推荐阅读