使用Amazon SNS给Android推送配置TTL失效,遗留参数time_to_live生效
更新
当使用遗留的time_to_live参数而非ttl参数时,功能可以正常工作。我当前可用的Message内容如下:
Message = $"{\"GCM\": \"{\\\"priority\\\": \\\"high\\\", \\\"data\\\":{data}, \\\"ttl\\\":\\\"0s\\\", \\\"time_to_live\\\": 0 }\" }";
我有以下疑问:
- 为何AWS仅支持遗留的
time_to_live参数,而非ttl? - 像我这样同时设置两者是否合理?
AWS.SNS.MOBILE.FCM.TTL为何无法生效?根据文档,它应优先于消息本身的设置,是否是我使用了错误的值?
原始问题
我使用AWS SNS推送通知,整体运行良好。现在尝试将推送通知的time to live(TTL)配置为0,因为我只希望应用能立即处理时才接收推送消息。
当前我使用以下C#代码片段(运行在Azure App Service中)。推送通知可以送达,但TTL设置未被遵守:
var data = JsonHelper.SerializeIgnoreNull(data).Replace("\\", "\\\\").Replace("\"", "\\\""); var sns = new AmazonSimpleNotificationServiceClient(snsAccessKey, snsAccessSecret); var data = JsonHelper.SerializeIgnoreNull(data).Replace("\\", "\\\\").Replace("\"", "\\\""); var publishRequest = new PublishRequest() { TargetArn = arn, Message = $"{\"GCM\": \"{\\\"priority\\\": \\\"high\\\", \\\"data\\\":{data} }\", \"AWS.SNS.MOBILE.FCM.TTL\":0 }", MessageStructure = "json" }; var result = sns.Publish(publishRequest);
类似的设置在iOS平台上可以正常生效。
针对Android,我还尝试了多种Message属性的构造方式:
- 在GCM对象内添加ttl属性:
Message = $"{\"GCM\\\": \"{\\\"priority\\\": \\\"high\\\", \\\"data\\”{data}, \\\"ttl\\\": 0 }\", \"AWS.SNS.MOBILE.FCM.TTL\":0 }",
- 将AWS属性放入GCM对象内:
Message = $"{\"GCM\\\": \"{\\\"priority\\\": \\\"high\\\", \\\"data\\\":{data}, \\\"ttl\\\": 0, \\\"AWS.SNS.MOBILE.FCM.TTL\\\":0 }\"}",
- 将ttl和AWS属性都放在GCM对象外:
Message = $"{\"GCM\\\": \"{\\\"priority\\\": \\\"high\\\", \\\"data\\\":{data} }\", \"ttl\": 0, \"AWS.SNS.MOBILE.FCM.TTL\":0 }",
- 仅设置ttl为字符串"0s":
Message = $"{\"GCM\": \"{\\\"priority\\\": \\\"high\\\", \\\"data\\\":{data} , \\\"ttl\\\":\\\"0s\\\" }\" }";
- 通过对象的MessageAttributes设置AWS属性:
Dictionary<string, MessageAttributeValue> attributes = new Dictionary<string, MessageAttributeValue>(); attributes.Add("AWS.SNS.MOBILE.FCM.TTL", new MessageAttributeValue() { StringValue = "0", DataType = "Number" }); publishRequest.MessageAttributes = attributes;
根据AWS SNS TTL文档说明:TTL消息属性用于指定SNS必须将消息传递到端点的最长时间(单位为秒)。我认为应该使用属性或第一种方式,但都未生效。
问题解答
1. 为何AWS仅支持遗留的time_to_live参数,而非ttl?
AWS SNS对FCM的适配存在版本兼容性滞后问题。FCM早期继承GCM的遗留字段使用time_to_live作为TTL参数(数值型,单位秒),后续才推出标准化的ttl参数(带单位的字符串格式,如"0s")。但目前AWS SNS的FCM推送模块仍优先兼容遗留的time_to_live字段,对新的ttl参数解析支持不完善,导致直接设置ttl无法生效。
2. 同时设置ttl和time_to_live是否合理?
不建议同时设置两者。FCM接收消息时若同时存在两个字段,会优先采用新规范的ttl参数,但AWS SNS本身无法正确传递ttl到FCM服务器,反而可能因字段冲突导致解析异常。既然测试验证time_to_live能正常生效,建议只保留time_to_live: 0即可,无需额外设置ttl。
3. AWS.SNS.MOBILE.FCM.TTL为何无法生效?
这个属性失效主要有两点原因:
- 参数位置错误:该属性属于SNS的全局消息属性,不能嵌套在GCM对象内部,也不能直接写在Message的JSON根节点中,必须通过
MessageAttributes字典设置。 - 数值格式问题:部分AWS SDK版本存在类型解析bug,即使文档标注为Number类型,实际需要传递字符串格式的数值(如"0"而非0),且
DataType需设置为"String"而非"Number"。正确设置方式如下:
Dictionary<string, MessageAttributeValue> attributes = new Dictionary<string, MessageAttributeValue>(); attributes.Add("AWS.SNS.MOBILE.FCM.TTL", new MessageAttributeValue() { StringValue = "0", DataType = "String" }); publishRequest.MessageAttributes = attributes;
另外,若同时设置了消息体内的time_to_live,根据SNS文档,AWS.SNS.MOBILE.FCM.TTL优先级更高,但前提是属性设置正确。如果仍不生效,需检查SNS端点配置是否启用了TTL支持,以及目标设备的FCM版本是否兼容该属性传递。
内容的提问来源于stack exchange,提问作者Edwin Vermeer

