주의사항
⚠️Firebase 프로젝트 에서 다운받은 google-services.json 파일을 추가해야합니다.
목차
- 인트로, 프로젝트 셋업
- 기본 UI 구성하기
- Cloud Messaging 소개
- Cloud Messaging 구성하기
- Cloud Messaging 연동하기
- Notification구현하기 - 1
- Notification구현하기 - 2
결과화면

1) 파이어베이스 코틀린 연동
Firebase란 구글에서 인수한 'Firebase'에서 만든 개발 플랫폼이다.
푸시 알림을 보내거나, 데이터를 서버에 저장하거나, 계정을 이용해 로그인하는 등의 작업을
아주 쉽고 편리하게 사용할 수 있게 도와주는 녀석이다.
안드로이드뿐만 아니라 IOS도 사용이 가능하니 사용 방법을 익혀두면 아주 좋다.
무료로 사용 가능하지만 일정량 이상 사용하기 위해서는 요금제에 가입해야 한다.
파이어베이스를 코틀린에 연동을 하기 위해서는 FireBase에 접속하여 로그인 후 Console로 이동한다.

그 이후 프로젝트 추가를 하여 원하는 프로젝트 Name을 넣어준다. 프로젝트 생성 중 받은 google-services.json 파일을 Project의 App 수준 폴더에 넣어준다. 그리고 프로젝트 수준의 build.gradle에
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.3"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
classpath 'com.google.gms:google-services:4.3.10'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
해당 dependencies와 google() mavenCentral(), classpath등을 추가 해 파이어베이스를 사용할 수 있도록 만들어 준다.
app 수준의 build.gradle()은 아래와 같이 설정해준다.
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'com.google.gms.google-services'
}
최상위 plugins에 'com.google....' 과 같은 id 형식으로 추가해주고 맨 아래 dependences에 자기가 firebase에 이용할 기능을 추가하는 형식으로 넣어주면 된다. 여기서 나는 아래와같이 추가해주었다.
implementation platform('com.google.firebase:firebase-bom:29.0.3')
implementation 'com.google.firebase:firebase-messaging-ktx'
implementation 'com.google.firebase:firebase-analytics-ktx'
}
파이어베이스 메시징 기능과 가장 기초적인 firebase-bom기능을 추가해주었고 마지막 간단하게 toyProject로 진행할 앱에서 analytics는 있어도 되고 없어도 되는 기능이다.
그러면 이제 파이어베이스의 연동기능은 마무리 됐다.
2) 파이어베이스 메시징 이용하기
푸시 알림으로 보낼 수 있는 메시지는 2가지 유형이 있다.
Notification은 앱이 포그라운드일 때 (앱이 실행 중일 때)만 푸시 알림이 오고
Data는 포그라운드/백그라운드 상관없이 푸시알림이 도착한다.
(Notification과 Data를 같이 쓰는 경우도 있지만 논외로 하겠다)
이 말만 들어보면 Data를 쓰지 않을 이유가 없을 것 같다.
실제로 어느 블로그를 보니 회사에서도 이유 불문하고 Data를 쓴다는 글을 보았는데
이유도 없이 Notification이 있을 것 같진 않다.
공식문서 : https://firebase.google.com/docs/cloud-messaging/concept-options?hl=ko 에서 확인 가능하다.
앱의 매니페스트에 다음을 추가해야한다.
- FirebaseMessagingService를 확장하는 서비스를 추가합니다. 백그라운드에서 앱의 알림을 수신하는 것 외에 다른 방식으로 메시지를 처리하려는 경우에 필요합니다. 포그라운드 앱의 알림 수신, 데이터 페이로드 수신, 업스트림 메시지 전송 등을 수행하려면 이 서비스를 확장해야 합니다.
<service android:name=".MyFirebaseMessagingService"
android:exported="false"> // 사진 공유 시 여러 앱들이 뜨는 것처럼 그런 기능을 막는다는 의미 !
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"></action>
</intent-filter>
</service>
onNewToken는 토큰을 생성하는 메서드이다.
onMessageReceived는 메시지를 수신하는 메서드이다.
메시지에 제목이나 내용이 들어있는지 검사하고 문제가 없다면 sendNotification을 호출한다.
sendNotification은 알림을 생성하는 메서드이다. 아이콘은 어떻게 할 건지, 알림 소리는 어떻게 할건지 등
이런 세세한 옵션을 설정하고 알림을 생성하면 비로소 푸시 알림이 뜨게 되는 것이다. 여기서는 사용하지 않는다.
Android 8.0(API 수준 26)부터는 모든 알림을 채널에 할당해야 합니다. 채널마다 채널의 모든 알림에 적용되는 시각적/음향적 동작을 설정할 수 있습니다. 그런 다음 사용자는 이 설정을 변경하고 앱에서 차단하거나 표시해야 하는 알림 채널을 결정할 수 있습니다.
3) FirebaseMessagingService 만들기
먼저 알림 채널을 만들려면 다음 단계를 따라야한다.
- 고유한 채널 ID, 사용자가 볼 수 있는 이름, 중요도 수준을 사용하여 NotificationChannel 객체를 구성합니다.
- 선택적으로 setDescription()을 사용하여 시스템 설정에서 사용자에게 표시되는 설명을 지정합니다.
- 알림 채널을 createNotificationChannel()에 전달하여 등록합니다.
private fun createNotificationChannel() { // channel 생성하는 과정 !!~!
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT
)
channel.description = CHANNEL_DESCRIPTION
(getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager)
.createNotificationChannel(channel)
}
}
위와같이 순서에 따라 정의를 해주면 이렇게 채널이 생성 된다. 그리고 생성된 채널에 의해 알림을 끄고 킬 수 있다.
이번앱에서는 notification을
package com.example.aop_part3_chaptor01
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.content.Context
import android.content.Intent
import android.os.Build
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
open class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onNewToken(p0: String) {
super.onNewToken(p0)
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
createNotificationChannel()
val type = remoteMessage.data["type"]?.let {
NotificationType.valueOf(it)
}
val title = remoteMessage.data["title"]
val message = remoteMessage.data["message"]
type ?: return
NotificationManagerCompat.from(this).notify(type.id, createNotification(type, title, message))
}
private fun createNotificationChannel() { // channel 생성하는 과정 !!~!
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT
)
channel.description = CHANNEL_DESCRIPTION
(getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager)
.createNotificationChannel(channel)
}
}
private fun createNotification(
type: NotificationType,
title: String?,
message: String?
): Notification {
val intent = Intent(this,MainActivity::class.java).apply{
putExtra("NotificationType", "${type.title} 타입")
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) // Stack 구조에서 TOP에는 Single 한개만 있는 것 화면이 한개 밖에 없음
// B에서 B화면 으로 이동하는 경우 기존화면을 갱신하면
}
val pendingIntent = PendingIntent.getActivity(this,type.id,intent,FLAG_UPDATE_CURRENT)
// pendingIntent란 ? 누군가한테 인텐트를 다룰 수 있는 권한을 준다고 생각!
val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(title)
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.setAutoCancel(true) // 클릭했을때 자동으로 Notification이 닫힌다.
when (type) {
NotificationType.NORMAL -> Unit
NotificationType.EXPENDABLE -> {
notificationBuilder.setStyle(
NotificationCompat.BigTextStyle()
.bigText(
"😁😒😊☺️😘😭😭☺️😳" +
"😔😉😉😌😉😌🙈🙈👀" +
"🙈👀😜😑😜😑😜😜😋😄😄" +
"😔😉😉😌😉😌🙈🙈👀" +
"🙈👀😜😑😜😑😜😜😋😄😄" +
"🙈👀😜😑😜😑😜😜😋😄😄"
)
)
}
NotificationType.CUSTOM -> {
notificationBuilder.setStyle(NotificationCompat.DecoratedCustomViewStyle())
.setCustomContentView(
RemoteViews(
packageName,
R.layout.view_custom_notification
).apply {
setTextViewText(R.id.title,title)
setTextViewText(R.id.message, message)
}
)
}
}
return notificationBuilder.build()
}
companion object {
private const val CHANNEL_NAME = "Emogi Party"
private const val CHANNEL_DESCRIPTION = "Emogi Party를 위한 채널"
private const val CHANNEL_ID = "Channel Id"
}
}
최종코드,
'안드로이드 > 앱개발(Android)' 카테고리의 다른 글
(코틀린 kotlin) 알람 앱 (0) | 2022.02.11 |
---|---|
(코틀린 kotlin) 명언앱 (0) | 2022.02.05 |
(코틀린 kotlin) 웹뷰 앱 (0) | 2022.01.25 |
(코틀린 kotlin) 녹음기 앱 (0) | 2022.01.24 |
(코틀린 kotlin) 타이머 앱 (0) | 2022.01.22 |