user3609216
user3609216

Reputation: 73

Amazon SNS - Sending push notifications to several devices

I'm trying to send push notifications to several devices in one shot. For that, I'm doing the following:

I'm trying to send a custom JSON to my apps. The content is:

{"APNS_SANDBOX":"{\"aps\":\"{\\\"u\\\":\\\"1\\\"}\"}"}

Though, I'm getting a InvalidParameter error sending the JSON. The error detail is

"Message Structure - No default entry in JSON message body"

The strange thing is that the very same JSON sent to a single device (publishing to an endpointarn) is working.

Here is my code:

AmazonSimpleNotificationServiceClient client = new AmazonSimpleNotificationServiceClient(ssAmazonToken.ssSTAmazonToken.ssAccessKey, ssAmazonToken.ssSTAmazonToken.ssSecretKey, solveRegionEndpoint(ssRegionEndpoint));

//create topic
CreateTopicRequest topicRequest = new CreateTopicRequest();
string topicName = Guid.NewGuid().ToString();
topicRequest.Name = topicName;
log(ssIsDebugMode, "Name (" + topicRequest.Name + ")", module);
CreateTopicResponse topicResponse = client.CreateTopic(topicRequest);
ssTopicArn = topicResponse.TopicArn;

//subscribe endpoints to the topic
foreach(RCAmazonSNSDeviceRecord endpoint in ssDevices) 
{
    SubscribeRequest subscribeRequest = new SubscribeRequest();
    subscribeRequest.TopicArn = topicResponse.TopicArn;
    subscribeRequest.Endpoint = endpoint.ssSTAmazonSNSDevice.ssEndpointArn;
    subscribeRequest.Protocol = "application";

    log(ssIsDebugMode, "TopicArn (" + subscribeRequest.TopicArn + ") "
                     + "Endpoint (" + subscribeRequest.Endpoint + ") "
                     + "Protocol (" + subscribeRequest.Protocol + ") ", module);

    SubscribeResponse subscribeResponse = client.Subscribe(subscribeRequest);

    /*ConfirmSubscriptionRequest confirmSubsRequest = new ConfirmSubscriptionRequest();
    confirmSubsRequest.AuthenticateOnUnsubscribe = true;
    confirmSubsRequest.TopicArn = topicResponse.TopicArn;*/
}

//publish message to the topic
PublishRequest publishRequest = new PublishRequest();
publishRequest.TopicArn = topicResponse.TopicArn;
publishRequest.MessageStructure = ssIsJSON ? "json" : "";
publishRequest.Message = ssMessageContent;

log(ssIsDebugMode, "TargetArn (" + publishRequest.TargetArn + ") "
                 + "MessageStructure (" + publishRequest.MessageStructure + ") "
                 + "Message (" + publishRequest.Message + ") ", module);


PublishResponse response = client.Publish(publishRequest);
ssAmazonResponse.ssSTAmazonResponse.ssResponseCode = response.HttpStatusCode.ToString();
ssMessageId = response.MessageId;
ssContentLength = response.ContentLength.ToString();

Upvotes: 4

Views: 2843

Answers (2)

Naveenam K
Naveenam K

Reputation: 37

So, when sending a SNS Notification to a topic, there’s no guarantee that all subscribers use the APNS messaging service. Because of this, SNS requires that you to also include a 'default' field in the JSON passed to it. This default field will be used for every other subscriber that does not fall within the APNS messaging service.

So in this case, you need to add another JSON element so there is a default message available if there's a non APNS subscriber.

{ "default": "Enter default message here", "APNS_SANDBOX": "{\"aps\":\"{\\"u\\":\\"1\\"}\"}" }

Few more example can be found on the bottom of this page here: http://docs.aws.amazon.com/sns/latest/dg/mobile-push-send-custommessage.html

Upvotes: 0

mkobit
mkobit

Reputation: 47239

SNS requires that there be a top level attribute named "default" in the Message JSON with a string value for the default protocol if you set the MessageStructure to json. From the Publish API documentation (emphasis mine):

MessageStructure

Set MessageStructure to json if you want to send a different message for each protocol. For example, using one publish action, you can send a short message to your SMS subscribers and a longer message to your email subscribers. If you set MessageStructure to json, the value of the Message parameter must:

  • be a syntactically valid JSON object;
  • and contain at least a top-level JSON key of "default" with a value that is a string.

You can define other top-level keys that define the message you want to send to a specific transport protocol (e.g., "http").

For information about sending different messages for each protocol using the AWS Management Console, go to Create Different Messages for Each Protocol in the Amazon Simple Notification Service Getting Started Guide.

Valid value: json

Type: String

Required: No

Upvotes: 2

Related Questions