Firebase云函数异步发送推送通知失败

3

我的目标是在用户发送消息时发送推送通知。我试图通过从Firestore数据库中检索所有推送令牌,并在实时数据库添加新消息时使用这些令牌发送多播消息来实现这一目标。

工作

第一个示例有效。没有令牌检索,令牌是硬编码的。我确实收到了通知。

exports.notifyUsers = functions.database.ref('/messages/{messageId}').onCreate((liveSnapshot, context) => {
    const name = context.params.messageId;
    const message = liveSnapshot.val().toString();
    const tokens = [
         "e6erA_qM...",
         "ePU9p_CI...",
    ];
    const payload = {
        notification: {
            title: `New message from ${name}`,
            body: message,
            badge: '1',
            sound: 'default'
        },
        tokens: tokens,
    }
    const res = admin.messaging().sendMulticast(payload);   
    console.log(`response: ${res}`);

无法工作

这个功能无法工作,我没有收到任何通知。

exports.notifyUsers = functions.database.ref('/messages/{messageId}').onCreate(async (liveSnapshot, context) => {
    const name = context.params.messageId;
    const message = liveSnapshot.val().toString();
    const snapshot = await admin.firestore().collection('users').get();
    const tokens = snapshot.docs.map(doc => doc.data().token);
    const payload = {
        notification: {
            title: `New message from ${name}`,
            body: message,
            badge: '1',
            sound: 'default'
        },
        tokens: tokens,
    }
    const res = await admin.messaging().sendMulticast(payload);     
    console.log(`response: ${res}`);

我已经使用下面的代码验证了从数据库中检索到的令牌与硬编码的令牌相同。

exports.notifyUsers = functions.database.ref('/messages/{messageId}').onCreate(async (liveSnapshot, context) => {
    const hardcodedTokens = [
         "e6erA_qM...",
         "ePU9p_CI...",
    ];
    const snapshot = await admin.firestore().collection('users').get();
    const tokens = snapshot.docs.map(doc => doc.data().token);
    let same = true;
    hardcodedTokens.forEach(el => {
        if (!tokens.includes(el)) {
           same = false;
        }
    });
    console.log(same);
})

这将在Firebase云函数控制台中记录true


该函数使用Node 12。

2个回答

1

以下代码可正常运行。

async function getTokens() {
    const snapshot = await admin.firestore().collection('users').get();
    return snapshot.docs.map(doc => doc.data().token);
}

exports.notifyUsers = functions.database.ref('/messages/{messageId}').onCreate(async (snapshot, context) => {
    const name = context.params.messageId;
    const message = snapshot.val().toString();
    const tokens = await getTokens();
    const payload = {
        notification: {
            title: `New message from ${name}`,
            body: message,
        },
        tokens: tokens,
    };
    await admin.messaging().sendMulticast(payload);
})

我记录了我的响应,如下所示:
const res = await admin.messaging().sendMulticast(payload);
console.log('response:', JSON.stringify(res));

这个记录了以下内容:
response: {"responses":[{"success":false,"error":{"code":"messaging/invalid-argument","message":"Invalid JSON payload received. Unknown name \"sound\" at 'message.notification': Cannot find field."}},{"success":false,"error":{"code":"messaging/invalid-argument","message":"Invalid JSON payload received. Unknown name \"sound\" at 'message.notification': Cannot find field."}}],"successCount":0,"failureCount":2}

基于此,我认为问题出在负载的通知部分的 sound 参数上。删除后它就可以工作了。


1

我最近遇到了类似的问题,并根据Firebase文档将Android和iOS特定字段分开解决了它:

   const message = {
  "notification": {
    "title": `New message from ${name}`,
    "body": message,
  },
  'apns': {
    'payload': {
      'aps': {
        'badge': 1,
      },
    },
  },
  'android':{
    'notification':{
      'notificationCount': 1,
    },
  },
  "tokens": tokens,
}

链接无法访问。 - Josh Mathews
这个链接应该有效:https://web.archive.org/web/20210817164151/https://firebase.google.com/docs/reference/admin/node/admin.messaging.MulticastMessage不确定为什么文档会出现404错误。这里有一个现有文档的链接,但它使用了getMessaging(),似乎是一种过时的方法。我刚刚使用了以下负载:{ notification: { title: "title", body: "body" }, content_available: true, tokens: [...] }并且它按预期工作。 - Josh Mathews
找到了当前的文档。他们已经更新了他们的API,使用TypeScript代替了以前的语言。有效载荷应该采用以下接口的形式:https://firebase.google.com/docs/reference/admin/node/firebase-admin.messaging.basemessage.md#basemessage_interface您能否更新链接? - Josh Mathews
我更新了链接。 - jon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接