最近有个日本项目,推送这块甲方非要用AWS+FCM,心中顿时一万个草泥马奔腾而过。
AWS号称多平台适应,然而,通用的结果就是不通用。简单说下需要准备的材料。
①.IAM。亚马逊的统一认证入口。
②.AWS-SNS平台应用程序。需要在AWS管理控制台注册,很简单,看说明就行了。
③.FCM。Google的消息推送平台(需要XX上网工具,你懂的)。在平台注册应用,并且记录一个叫SenderId的东西。
④.react-native-push-notification。我们的应用是RN的,并且客户说必须用这个包(已很久没人更新,再次草泥马奔腾而过)。
这里再次吐槽下日本的互联网设计人员,白痴+自大狂。狗屁不懂还特么装大爷。
手机环境,Google Play服务(注意不是商店是服务),Google 服务框架。
这两项必须,有些时候需要XX上网工具才能连上。
1.APP注册流程。
首先,APP在安装后需要在FCM平台注册,并获取一个Token。大致流程如下(EXCEL做的,懒了一下):
上述流程最重要的生成物就是④中的ARN,这个东西是每个设备在AWS上的唯一标识码。
1.1 手机在FCM平台注册,我们是RN程序,所以用的是开头所说的react-native-push-notification,关键代码如下:
PushNotification.configure({
onRegister: onRegister, //注册成功后的回调函数,注册的时候记得翻墙
onNotification: onNotification, //推送消息过来以后调用的回调函数
senderID: // 开头所讲到的SenderId,
popInitialNotification: true,
requestPermissions: true,
});
其中onRegister的参数是FCM平台给返回的Token,取法是token.token
onNotification的参数是AWS推送来的消息,json格式。
1.2 token转arn的操作,我只研究了java版,关键代码如下:
/**
*
* @param customData 客户数据
* @param platformToken FCM的token
* @param applicationArn AWS应用的ARN
* @param amazonSNS SNS示例
* @return
*/
private static CreatePlatformEndpointResult createPlatformEndpoint(
String customData, String platformToken,
String applicationArn, AmazonSNS amazonSNS) {
CreatePlatformEndpointRequest platformEndpointRequest = new CreatePlatformEndpointRequest();
platformEndpointRequest.setCustomUserData(customData);
String token = platformToken;
platformEndpointRequest.setToken(token);
platformEndpointRequest.setPlatformApplicationArn(applicationArn);
return amazonSNS.createPlatformEndpoint(platformEndpointRequest);
}
在返回的实例中会有一个设备的ARN,取法:CreatePlatformEndpointResult.getEndpointArn()
有了设备的ARN,就可以用AWS推送消息了。
2.推送消息
推送消息的流程大致如下:
JAVA端的推送代码如下:
public static PublishResult sendSNSMessage(String deviceId, String message, String subject, String userData) {
final AWSCredentials awsCredentials = new AWSCredentials() {
public String getAWSAccessKeyId() {
return // IAM上获取的Access key id;
}
public String getAWSSecretKey() {
return // IAM上获取的Secret key id;
}
};
AWSCredentialsProvider provider = new AWSCredentialsProvider() {
public AWSCredentials getCredentials() {
return awsCredentials;
}
public void refresh() {}
};
AmazonSNS amazonSNS = null;
try {
amazonSNS = AmazonSNSClientBuilder.standard().
withCredentials(provider).withRegion("ap-northeast-1").build();
} catch (Exception e) {
}
String platformApplicationArn = // 应用的ARN,在AWS管理平台上注册的;
CreatePlatformEndpointResult platformEndpointResult = createPlatformEndpoint(
userData, deviceId, platformApplicationArn, amazonSNS);
// 数据
JSONObject sjon = new JSONObject();
JSONObject data = new JSONObject();
JSONObject messageJson = new JSONObject();
messageJson.put("message", "From Java Push Test.");
messageJson.put("notificationId", "notice19");
data.put("data", messageJson); // 次外层的key不能改
sjon.put("GCM", data.toString()); // 最外层的key不能改
PublishResult result = amazonSNS.publish(
new PublishRequest()
.withMessageStructure("json") // 必须
.withTargetArn(设备的ARN)
.withSubject(subject)
.withMessage(sjon.toString())
);
System.out.println(result.getMessageId());
return result;
}
接收端,没有特殊处理。
react-native-push-notification的配置方式在git上有,照做就可以了。
本次只做了安卓版。
踩坑,仅供参考。
邮箱:koala6403@163.com