node.js - AWS SNS always publish duplicate messages to Platform Applications Endpoint
问题描述
I found an odd behavior of AWS SNS when publishing multiple messages to Apple Push Notifications at the same time from AWS Lambda - every published message is received TWICE by the subscriber.
My code is as follows
handler.js
const uuid = require('uuid')
const aws = require('aws-sdk');
const sns = new aws.SNS({ apiVersion: '2010-03-31' })
const messageSender = async (event, context, callback) => {
// sending 3 messages one after another
publishMessage("title1", "message1")
publishMessage("title2", "message2")
publishMessage("title3", "message3")
return []
}
const publishMessage = (title, message) => {
sns.publish({
Message: JSON.stringify({
"default": "default message",
"APNS_SANDBOX": JSON.stringify({
"aps": {
"alert": {
"title": title,
"body": message
},
"badge": 1,
"id": uuid.v4(),
"foo": "bar"
}
})
}),
MessageStructure: 'json',
TopicArn: process.env.TOPIC_ARN
}).promise()
console.log(`Message for topic is published: ${message}`)
}
However if I publish only one message like the below, the exact message is received only once.
const messageSender = async (event, context, callback) => {
publishMessage("title1", "message1")
return []
}
Any ideas why receiving the same message twice when sending multiple messages?
EDIT
After playing the publish API a while I found the following.
The duplication is caused by a potential Amazon SNS bug(?). If not sending JSON format the duplication error disappears. e.g. Remove the MessageStructure: 'json'
and change the message to be String only as follows.
sns.publish({
Message: "this is a sample message",
TopicArn: process.env.TOPIC_ARN
}).promise()
This is a workaround of the issue however the underlying cause of the original issue is still unknown.
The workaround has drawbacks as it cannot customise the notification with APN attributes such as adding a title to the push notifications as well as badges.
Any other workaround or whoever knows the fixes?
解决方案
I had the same problem, but the above didn't help.
In my case, I tracked it down to using a callback function AND the .promise() method.
i.e. I had something like:
await SNS.publish({
TopicArn: process.env.SNS_TOPIC,
Message: message,
MessageAttributes: {
source: {DataType: 'String', StringValue: source},
level: {DataType: 'String', StringValue: level}
},
}, function(err, data) {
if (err) {
console.log('SNS_notify: error -', err);
} else {
console.log('SNS_notify: sent -', data.MessageId);
}
).promise();
Changing this to:
let data = await SNS.publish({
TopicArn: process.env.SNS_TOPIC,
Message: message,
MessageAttributes: {
source: {DataType: 'String', StringValue: source},
level: {DataType: 'String', StringValue: level}
},
}).promise();
console.log('SNS_notify: sent -', data.MessageId);
fixed the problem.
推荐阅读
- javascript - 如何从同一个 js 文件中的第一个导出函数调用第二个导出函数
- mysql - MYSQL - 尽管使用 ORDER BY id,但使用 LIMIT 和 GROUP BY 时的非确定性顺序
- node.js - 从模拟器上的 Firebase 存储流式传输文件时 Firebase 功能超时
- mainframe - 在 JCL 中对 JOB 和 EXEC 使用 COND
- python - 如果脚本未正确运行,似乎无法将错误写入输出文件
- reactjs - 反应弹簧动作僵硬,好像没有质量或摩擦
- javascript - 如何在新页面中显示 JS/Html 调查的结果?
- excel - Excel - 月平均
- r - 向数据框添加平均值
- python - 如何在 plotly express 中更改散点矩阵中的轴限制?