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());

 

       

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章