FirebaseMessagingService
FCM 푸시 알림을 받는 곳으로, 푸쉬 알림 처리는 이 곳에서 하게된다.
https://firebase.google.com/docs/cloud-messaging/android/receive?hl=ko
공식문서를 따라 Manifest와 FirebaseMessagingService() class 를 만들어 주면 된다!
안드로이드 버전에 따라 알림 처리 방식이 다르니 이 점도 유의해야 한다.
FCM notification 방식에는 data 와 notification 두 가지가 있고, 받는 방식이 다르다.
두가지의 용도를 다르게 사용한다면 처리를 각각 해주는 것이 옳다.
https://dunkey2615.tistory.com/69
위 블로그에 잘 설명되어 있으니 한번 보시는 걸 추천드립니다.
class MyFirebaseMessagingService : FirebaseMessagingService() {
val TAG = "MSG_Firebase"
lateinit var listener : NoticeAPIView
// 메세지가 수신되면 호출
override fun onMessageReceived(remoteMessage: RemoteMessage) {
Log.i(TAG, remoteMessage.toString());
// 서버에서 직접 보냈을 때
if(remoteMessage.notification != null){
sendNotification(remoteMessage.notification?.title, remoteMessage.notification?.body!!)
if (true) {
scheduleJob();
} else {
handleNow();
}
}
// 다른 기기에서 서버로 보냈을 때
else if(remoteMessage.data.isNotEmpty()){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
sendMessageNotification(remoteMessage.data )
}
else{
sendNotification(remoteMessage.notification?.title, remoteMessage.notification?.body!!)
}
if (true) {
scheduleJob();
} else {
handleNow();
}
}
}
private fun handleNow() {
Log.d(TAG, "Short lived task is done.")
}
private fun scheduleJob() {
val work = OneTimeWorkRequest.Builder(MyWorker::class.java)
.build()
WorkManager.getInstance().beginWith(work).enqueue()
}
// Firebase Cloud Messaging Server 가 대기중인 메세지를 삭제 시 호출
override fun onDeletedMessages() {
super.onDeletedMessages()
}
// 메세지가 서버로 전송 성공 했을때 호출
override fun onMessageSent(p0: String) {
super.onMessageSent(p0)
Log.e(TAG, "sending success ")
}
// 메세지가 서버로 전송 실패 했을때 호출
override fun onSendError(p0: String, p1: Exception) {
super.onSendError(p0, p1)
}
// 새로운 토큰이 생성 될 때 호출
override fun onNewToken(token: String) {
super.onNewToken(token)
}
fun sendNotification(title: String?, body: String) {
val uniId: Int = (System.currentTimeMillis() / 7).toInt()
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) // 액티비티 중복 생성 방지
val pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT) // 일회성
val channelId = BuildConfig.DEFAULT_NOTIFICATION_CHANNEL_ID
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) // 소리
val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.ic_launcher) // 아이콘 설정
.setContentTitle(title) // 제목
.setContentText(body) // 메시지 내용
.setAutoCancel(true)
.setSound(defaultSoundUri) // 알림 소리
.setContentIntent(pendingIntent) // 알림 실행 시 Intent
.setDefaults(Notification.DEFAULT_SOUND)
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// 오레오 버전 이후에는 채널이 필요
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
val channel = NotificationChannel(channelId, "Notice", NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(channel)
channel.apply {
setShowBadge(false)
}
}
notificationManager.notify(uniId, notificationBuilder.build()
}
private fun sendMessageNotification( Message : Map<String, String>){
val uniId: Int = (System.currentTimeMillis() / 7).toInt()
val title = Message["title"]!!
val body = Message["body"]!!
// PendingIntent : Intent 의 실행 권한을 외부의 어플리케이션에게 위임
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, uniId, intent, PendingIntent.FLAG_ONE_SHOT)
// 알림 채널 이름
val channelId = BuildConfig.DEFAULT_NOTIFICATION_CHANNEL_ID
// 알림 소리
val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
// 알림에 대한 UI 정보와 작업을 지정
val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.ic_launcher) // 아이콘 설정
.setContentTitle(title) // 제목
.setContentText(body) // 메시지 내용
.setAutoCancel(true)
.setSound(soundUri) // 알림 소리
.setContentIntent(pendingIntent) // 알림 실행 시 Intent
.setDefaults(Notification.DEFAULT_SOUND)
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// 오레오 버전 이후에는 채널이 필요
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
val channel = NotificationChannel(channelId, "Notice", NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(channel)
channel.apply {
setShowBadge(false) // 뱃지 사용안함
}
}
notificationManager.notify(uniId, notificationBuilder.build()) // 여기서 uniID을 0으로 설정하면 상태바에 최신의 하나의 알림만 보이게 된다.
}
}