I am trying to send a JSON message to an iOS client. When I send the message as plain text it work just fine. However, setting the "MessageStructure: 'json'" and then the "Message" as a JSON object, as detailed in the AWS document I get a funny error: "InvalidParameterType: Expected params.Message to be a string"
If you want to send different messages for each transport protocol, set the value of the MessageStructure parameter to json and use a JSON object for the Message parameter. See the Examples section for the format of the JSON object. (From: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/frames.html)
I am sending:
params = {
MessageStructure: 'json',
Message: {
default: 'A notification from us!',
APNS_SANDBOX: {aps:{alert:"Hello and have a good day."}}
},
TargetArn: '...'
};
(I have also tried sending the APNS_SANDBOX as an escaped string, same issue...)
To me this seems like a major bug.
Any ideas?
The Message value has to be encoded as a string, so you can try calling JSON.stringify({ ... }) on your JSON structure and pass it through as a JSON encoded string. This documentation seems misleading to me-- there seems to be room for improvement here.
Man, I was going crazy on this issue and I swear I tried the JSON.stringify() before and it still was not working. I just did a complete new start, re-wrote the whole thing and tried the stringify method again. Magically; it works now.
Some times a simple, plain and different point of view (or explanation) makes a complete difference sense.
Thank you. Next time I am around your city you have a free burger + beer (same applies if you are around my city)
:)
And yes, I agree; the AWS documentation has room for a lot of improvement. A JSON encoded string is not a JSON object, not to me, at least.
Another question; what about this:
'InvalidParameter: Invalid parameter: JSON must contain an entry for \'default\' or \'APNS_SANDBOX\'
I was sending:
params = {
MessageStructure: 'json',
Message: {
APNS_SANDBOX: {aps:{alert:"Hello and have a good day."}}
},
TargetArn: '...'
};
The error says "or" so in my opinion the "APNS_SANDBOX" should do the trick, no?
That's a good question (and point). This came up in the Ruby SDK a while back (https://github.com/aws/aws-sdk-ruby/issues/336) and it looks like the right way was to use both parameters there. I would suggest opening a thread in the SNS forums to see if they have any insight on what is going on with that validation error message. Perhaps they can make it more clear.
Thank you, will do.
Have a good one.
And found another issue which might be related to this module:
params = {
MessageStructure: 'json',
Message: {
default: "I am default":
APNS_SANDBOX: {aps:{alert:"Hello and have a good day."}}
},
TargetArn: '...'
};
And guess what I receive on my iOS device? - Yes, the "default". It seems to be overriding the whole object's other properties. If, of course, I try to put the payload into the "default" it also complains.
Any ideas?
Using Amazon is really starting to get frustrating.
I have same issue when using AWS SNS CLI.
@gloopeezza if this same behavior occurs in the CLI I would definitely recommend opening a thread on the SNS forums as this would likely be a service issue, and not specific to the JS SDK.
Found the issue about the "default" overriding the APNS property's value; the "Massage" itself must be encoded as a valid string, say JSON.stringify() for example. The trick is applying the same to the "APNS_SANDBOX". For example:
params = {
MessageStructure: 'json',
Message: JSON.stringify({
default: "I am default":
APNS_SANDBOX: JSON.stringify({aps:{alert:"Hello and have a good day."}})
}),
TargetArn: '...'
};
The above will make AWS SNS "ignore" the default and actually deliver what is expected.
I wish I had access to the SNS documentation, I would make quite some changes.
Anyway, hope this helps somebody.
@lsegal Indeed a SNS issue and not JS SDK related. Sadly no one from the SNS team seems to read the forums as issues mentioned ages ago still persist, but that is a whole new story, I guess.
Thank you.
@aichholzer glad you figured out the right way to call this API. I've sent a note to the SNS team so we can get more eyes on this documentation issue on the forum thread you posted. I realize misleading and/or incorrect documentation can be frustrating, but we are always trying to improve our docs, so hopefully we can do a better job explaining these mobile push APIs in the near future. If you still don't get a response on the forums, ping me here and I'll be glad to do some more digging.
Thanks for your investigation. CLI and Java SDK working as well.
@gloopeezza most welcome, I know how frustrating it can be.
@aichholzer Thanks, you saved our asses. SNS documentation is really lacking very important pieces of information.
@pixelogik glad it was of any help.
Guys,
I'm trying my luck in this forum. I'm having an issue with Amazon SNS when I try to send a push notification to several devices at the same time.
I've explained my issue here: https://forums.aws.amazon.com/thread.jspa?threadID=171981
Any help?
@aichholzer wow, thanks! - the double stringify is what made it work, it's stupid but it's perfect, thanks!
@typemismatch anytime!
This issue is still just as relevant as it was when it was posted. @lsegal There's still nothing in the documentation about JSON encoded strings. Your comment really helped me out.
Yes, I am not sure where the AWS team's priorities are.
yes this is definitely weird behavior, it doesn't make sense to set it to "json" if you are then forced to pass a string.
Thanks a lot man! Wasted around two hours with that !
@aichholzer Thank you!
@aichholzer Thank you!
:+1:
Same issue here. Serious issues with the documentation and would never have figured this json -> string stuff out myself.
Thanks, and please, someone fix those docs :/
Thanks you so much for this answer!
@aichholzer You're still saving people hours and hours of headaches! Thanks!
Thanks for the answer, never would have solved it without it! Cheers.
That's incredible that still in 2017 we have to dig in such old issues. Why not mention this example on the docs?
Anyway thank you @aichholzer 馃憤
For GCM the structure is like below, which is taken from this gist
let payload = {
GCM: {
data: {
message:'Hello world'
}
}
};
// first have to stringify the inner GCM object...
payload.GCM = JSON.stringify(payload.GCM);
// then have to stringify the entire message payload
payload = JSON.stringify(payload);
var params = {
MessageStructure: 'json',
Message: payload,
Subject: 'TEST SUBJECT',
TargetArn: 'TargetArn'
};
My GCM implementation is:
const params = {
Message: JSON.stringify({
default: "This is the message for you...",
GCM: JSON.stringify({
data: {
message: "Hello World",
}
})
}),
MessageStructure: "json",
TargetArn: 'arn:aws:...', // This is the endpointARN
};
const sns = new AWS.SNS();
sns.publish(params as any, function(err, data) {
if(err) {
console.log('error occured: ', err, err.stack);
} else {
console.log('Success: ', data);
}
});
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.
Most helpful comment
Found the issue about the "default" overriding the APNS property's value; the "Massage" itself must be encoded as a valid string, say JSON.stringify() for example. The trick is applying the same to the "APNS_SANDBOX". For example:
The above will make AWS SNS "ignore" the default and actually deliver what is expected.
I wish I had access to the SNS documentation, I would make quite some changes.
Anyway, hope this helps somebody.