[FCM] #4. Android 메시지 처리
[FCM] #2. Firebase 프로젝트 생성 및 Android 앱 FCM 설정
이번에는 Android에서 단순 메시지가 아닌 아이콘이나 이미지 메시지를 어떻게 처리하는지 알아본다.
우선 안드로이드 관련 코드들은 제외하고, 메시지 관련된 부분만 설명한다.
푸시 메시지는 FirebaseMessagingService 클래스를 상속받아 onMessageReceived 메소드를 오버라이딩 해서 커스텀하게 처리한다.
onMessageReceived 메소드에서 메시지 알림 처리를 하면 앱이 포그라운드, 백그라운드 상관없이 푸시 메시지가 도착한다.
코드 관련 정보는 #2. Firebase 프로젝트 생성 및 Android 앱 FCM 설정 부분에 있다.
@Override public void onMessageReceived(RemoteMessage remoteMessage) { // ... // TODO(developer): Handle FCM messages here. // Not getting messages here? See why this may be: https://goo.gl/39bRNJ Log.d(TAG, "From: " + remoteMessage.getFrom()); // Check if message contains a data payload. if (remoteMessage.getData().size() > 0) { Log.d(TAG, "Message data payload: " + remoteMessage.getData()); if (/* Check if data needs to be processed by long running job */ true) { // For long-running tasks (10 seconds or more) use Firebase Job Dispatcher. scheduleJob(); } else { // Handle message within 10 seconds handleNow(); } } // Check if message contains a notification payload. if (remoteMessage.getNotification() != null) { Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody()); } // Also if you intend on generating your own notifications as a result of a received FCM // message, here is where that should be initiated. See sendNotification method below. }
푸시 메시지 중 큰 아이콘 메시지, 이미지 메시지 등은 onMessageReceived 메서드에서 처리한다.
remoteMessage는 송신자 정보와 데이터 메시지 정보를 가지고 있다.
보통 데이터 메시지 안에 제목, 내용, 이미지 정보등을 포함하여 맞춤형 알림 처리를 한다.
이전 HTTP API 기준으로 아이콘 메시지, 이미지 메시지 처리를 해보자.
아이콘 메시지
메시지 정보
아래는 FCM 접속 서버에 발송하는 데이터 메시지 정보이다.
여기서 데이터 메시지는 커스텀하게 key,value를 설정할 수 있다. [FCM] #1. 소개 및 메시지 참고
{ "data": { "title":"😃제목😃", "body":"😃내용😃", "largeIcon":"https://t1.daumcdn.net/news/201902/13/ZDNetKorea/20190213133354225nmeh.jpg" }, "to":"사용자 토큰" }
onMessageReceived
private void onMessageReceived(RemoteMessage remoteMessage){ Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent, PendingIntent.FLAG_ONE_SHOT); String channelId = "one-channel"; String channelName = "My Channel One1"; String channelDescription = "My Channel One Description"; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT); notificationChannel.setDescription("channel description"); notificationChannel.enableLights(true); notificationChannel.setLightColor(Color.GREEN); notificationChannel.enableVibration(true); notificationChannel.setVibrationPattern(new long[]{100, 200, 100, 200}); notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); notificationManager.createNotificationChannel(notificationChannel); } Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId) .setSmallIcon(R.mipmap.ic_launcher) //제목 .setContentTitle(remoteMessage.getData().get("title")) //내용 .setContentText(remoteMessage.getData().get("body")) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); try { URL url = new URL(remoteMessage.getData().get("largeIcon")); //아이콘 처리 bigIcon = BitmapFactory.decodeStream(url.openConnection().getInputStream()); notificationBuilder.setLargeIcon(bigIcon); } catch (IOException e) { e.printStackTrace(); } NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(333 /* ID of notification */, notificationBuilder.build()); }
결과
이미지 메시지
메시지 정보
{ "data": { "title":"😃제목😃", "body":"😃내용😃", "imgUrl":"https://t1.daumcdn.net/news/201902/13/ZDNetKorea/20190213133354225nmeh.jpg" }, "to":"사용자 토큰" }
onMessageReceived
펼쳐진 상태 | 제목 | NotificationCompat.Builder.setContentTitle() |
내용 | NotificationCompat.Builder.setContentText() | |
줄여진 상태 | 제목 | NotificationCompat.BigPictureStyle().setBigContentTitle() |
내용 | NotificationCompat.BigPictureStyle()..setSummaryText() |
private void onMessageReceived(RemoteMessage remoteMessage){ Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 , intent, PendingIntent.FLAG_ONE_SHOT); String channelId = "one-channel"; String channelName = "My Channel One1"; String channelDescription = "My Channel One Description"; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT); notificationChannel.setDescription("channel description"); notificationChannel.enableLights(true); notificationChannel.setLightColor(Color.GREEN); notificationChannel.enableVibration(true); notificationChannel.setVibrationPattern(new long[]{100, 200, 100, 200}); notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE); notificationManager.createNotificationChannel(notificationChannel); } Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(remoteMessage.getData().get("title")) .setContentText(remoteMessage.getData().get("body")) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); try { URL url = new URL(remoteMessage.getData().get("imgUrl")); //이미지 처리 bigPicture = BitmapFactory.decodeStream(url.openConnection().getInputStream()); notificationBuilder.setStyle( new NotificationCompat.BigPictureStyle() .bigPicture(bigPicture) .setBigContentTitle(remoteMessage.getData().get("title")) .setSummaryText(remoteMessage.getData().get("body"))); } catch (IOException e) { e.printStackTrace(); } NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(333 /* ID of notification */, notificationBuilder.build()); }
결과
아이콘과 이미지를 같이 처리하면 아래와 같은 결과를 얻을 수 있다.