AWS SNS+Google FCM推送服务的使用

       近期在项目中需要用到AWS SNS服务,因为面向安卓平台,当然优先考虑谷歌的GCM(Google已更新为FCM)搭配,在开发中遇到几点问题,做一下记录,顺便给同行们参考。

       首先注册/拥有Google账号,在https://firebase.google.com/ 创建自己的项目,在Application栏添加自己的Android应用,根据提示一步步完成firebase的设置,生成对应的server_key即可,这里基本不会有任何问题,谷歌的帮助文档和截图说明十分详细。FCM设定完成后在Android App加入FirebaseMessagingService即可通过firebase的Cloud Messaging发送并测试FCM推送效果:

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.d("FCM", "onMessageReceived:" + remoteMessage.getFrom());
       
        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
            Log.d("FCM", "Message data payload: " + remoteMessage.getData());
        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.d("FCM", "Message Notification Body: " + remoteMessage.getNotification().getBody());

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
                createNotificationChannels(getApplicationContext());
            }else {
                sendNotification(remoteMessage.getNotification().getBody());
            }

        }
    }
}

       测试FCM可用后,开始创建自己的SNS服务,首先登陆AWS Console,在Services下拉菜单搜索SNS,就可以找到Simple Notification Service,然后按照SNS dashboard的Common Action完成create Topic 、Create platform application、Create Subscription、pulish Message 就可以发送Notification了,而为了绑定先前创建的FCM应用,在Create platform application时需要选择Push notification platform为Google Cloud Messaging(GCM),然后输入在Firebase添加自己Android App时产生的api_key,而同时需要注意的是,若需要安卓设备能够接收到Notification,需要在点击application ARN,然后添加对应安卓设备的platform Endpoint,Create platform endpoint时需要输入两条数据,第二个user data为用户任意输入内容,第一条的Device Token就是安卓设备从Google服务返回的token,取得Token需要在Android App加入FirebaseInstanceIdService,而为了方便Endpoint的生成,我们可以将Token自动添加到Endpoint中,并创建与Topic对应的Subscription,使安卓用户能够自动实现接收Topic所发出的通知,代码如下:

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
    public MyFirebaseInstanceIDService() {
    }

    @Override
    public void onTokenRefresh() {
        //For registration of token
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();

        //To displaying token on logcat
        Log.d("TOKEN", refreshedToken);
        //upload token to SNS endpoint
        sendTokentoSNS(refreshedToken);
    }

    private void sendTokentoSNS(String refreshedToken){
        String access_id = "********"; 
        String secret_key ="********";
        String appArn = "arn:aws:sns:us-west-2:********:app/GCM/xxx_client";
        String topicArn = "arn:aws:sns:us-west-2:********:ota-notify";
        AWSCredentials credentials = new BasicAWSCredentials(access_id,secret_key);
        AWSCredentialsProvider provider = new StaticCredentialsProvider(credentials);
        AmazonSNSClient snsClient = new AmazonSNSClient(provider);
                snsClient.setRegion(Region.getRegion(Regions.US_WEST_2));
        CreatePlatformEndpointRequest createPlatformEndpointRequest = new CreatePlatformEndpointRequest()
                .withPlatformApplicationArn()
                .withToken(refreshedToken)
                .withCustomUserData(Build.DEVICE);
        CreatePlatformEndpointResult result = snsClient.createPlatformEndpoint(createPlatformEndpointRequest);

        SubscribeRequest subscribeRequest = new SubscribeRequest().withTopicArn(topicArn)
                .withProtocol("application")
                .withEndpoint(result.getEndpointArn());
        snsClient.subscribe(subscribeRequest);
        Log.i("TOKEN","add token to SNS ");
    }

}

        以上基本实现了SNS通知接收和发送的框架,不过实际发送GCM通知时,还有一个问题需要解决,就是GCM在SNS里Message的格式,怎样发出对应的data和notification分类的消息,经过测试后,我使用了Gson来转换SNS需要的格式,发送出一条包含data和notification的通知,代码如下:

            String topicArn = "arn:aws:sns:us-west-2:********:ota-notify";
            //publish to an SNS topic
            String update = “a new update!”;
            
            Gson gson = new Gson();
            GCM gcm = new GCM();
            data data = new data();
            notification notification = new notification();
            SNSMessage snsMessage = new SNSMessage();
            
            notification.setTitle("AWS S3");
            notification.setSound("default");
            notification.setBody("you have "+update);
            data.setMessage("image update");
            gcm.setNotification(notification);
            gcm.setData(data);        
            snsMessage.setGcm(gson.toJson(gcm,GCM.class));
            snsMessage.setDefault("default message");                  
            
            String jsonstr = gson.toJson(snsMessage,SNSMessage.class);
            
            PublishRequest publishRequest = new PublishRequest()
                    .withTopicArn(topicArn)
                    .withSubject("update")
                    .withMessageStructure("json")                    
                    .withMessage(jsonstr);
    
            PublishResult publishResult = snsClient.publish(publishRequest);
            //print MessageId of message published to SNS topic
            System.out.println("MessageId - " + publishResult.getMessageId());

 

       

你可能感兴趣的:(AWS云服务,Java,SNS服务)