김호쭈
DevForYou
김호쭈
전체 방문자
오늘
어제
  • 분류 전체보기 (321)
    • • 데이터베이스(DB) (9)
      • __SQL__ (9)
    • •알고리즘(Algorithm ) (117)
      • 문제풀이 (99)
      • 스터디 (14)
      • 알고리즘 팁 (4)
    • •Compter Science (57)
      • Operating System (25)
      • Computer Network (1)
      • Computer Vision (16)
      • Artificial Intelligence (14)
      • Software Technology (1)
    • • 독서 (36)
      • Design Pattern (24)
      • 객체지향의 사실과 오해 (1)
      • Object Oriented Software En.. (11)
    • • 개발 (26)
      • React (3)
      • node.js (6)
      • Django (11)
      • Spring boot (6)
    • • 개발Tip (4)
      • GitHub (0)
    • •프로젝트 (2)
      • 물물 (2)
    • •App (54)
      • 안드로이드 with Kotlin (50)
      • 코틀린(Kotiln) (4)
    • •회고 (8)
    • •취준일기 (3)
    • • 기타 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • local저장소
  • 원격저장소
  • KMU_WINK
  • 로컬저장소
  • 깃허브데스크탑
  • ㄱ
  • GitHubDesktop
  • Remote저장소

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
김호쭈

DevForYou

[안드로이드&코틀린] 파이어베이스사용하여 알림보내기, Firebase Cloud Message, 범블비(bumblebee)버전에서 안드로이드 스튜디오 파이어베이스 연결하기, SDK설정 오류
•App/안드로이드 with Kotlin

[안드로이드&코틀린] 파이어베이스사용하여 알림보내기, Firebase Cloud Message, 범블비(bumblebee)버전에서 안드로이드 스튜디오 파이어베이스 연결하기, SDK설정 오류

2022. 3. 31. 01:28

 

# 결과물 미리보기

파이어베이스에서 메시보내기

파이어 베이스를 통하여 내 안드로이드 기기에 알림을 보내는 기능을 구현해봤다. 강의영상을 참고하기도 했지만 달라진 것도 많기 때문에 Firebase와 안드로이드 공식문서를 많이 참고했다. 

 

# 파이어베이스 연동하기 ( 안드로이드 스튜디오 범블비 버전 이상 )

시작하기에 앞서 파이어베이스를 내 안드로이드 프로젝트와 연동하는 작업이 필요하다. 안드로이드 스튜디오의 범블비 버전으로 올라감에 따라 build.gradle(project)에 추가하는 방법이 달려졌다. 이것때문에 살짝 애를 먹었다. 비슷한 것때문에 문제를 겪고 있는 사람들은 아래 내용을 참고하면 될 것 같다.

 

로그인 - Google 계정

하나의 계정으로 모든 Google 서비스를 Google 계정으로 로그인

accounts.google.com

먼저 파이어 베이스에서 프로젝트를 만들어준다. 

이후 앱을 추가해줄 것인데 여기서 프로젝트 ID와 json파일은 하라는대로 하면 된다.

##  범블비에서 Firebase SDK 추가

build.gradel(project)로 오면 아래 그림과 같이 가이드와 달라서 당황하게 될 것이다. 범블비 버전으로 업데이트 되면서 세부적인 내용은 settings.gradle에서 다룬다고 한다. 신경 쓸 필요 없이 build.gradle(project)에 아래처럼 코드를 추가해준다.

// build.gradle(proj)
buildscript {
    dependencies {
        classpath 'com.google.gms:google-services:4.3.10'
    }
}

plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
    id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

그리고 Sync Now를 누르면 싱크가 완료된다.

이후 build.gradle(app)에서 진행하는 건 그대로 적어 사용하면 된다.

// build.gradle(app)
plugins {
    // ...
}
apply plugin: 'com.google.gms.google-services'

dependencies {
	// ...
    // ...
    implementation platform('com.google.firebase:firebase-bom:29.2.1')
    implementation 'com.google.firebase:firebase-analytics-ktx'
    implementation 'com.google.firebase:firebase-messaging-ktx'
}

이제 파이어 베이스와 연동은 끝냈다. 알림을 위한 코드를 작성하자

 

# 코틀린으로 코드 작성하기

순서는 다음과 같다.

  1. 안드로이드 디바이스에 부여된 토큰값 알아내기
  2. Firebase <-> 안드로이드 기기사이에서 알림을 주고 받을 채널 만들어주기
  3. NotificationCompat 빌더를 만들어 빌드하기
  4. notify를 통하여 빌더 호출하기

 

## 1. 안드로이드 디바이스에 부여된 토큰값 알아내기

물론 실제 서비스에서는 토큰값을 Firebase에 내부적으로 보내주거나 다른 방식을 사용하겠지만 이번 예제에서는 하드코딩을 통해서 토큰값을 알아냈다. Firebase SDK를 추가해줬기 때문에 Firebase관련된 것을 사용할 수 있다.

// MainActivity.kt
private fun initFirebase() {
    FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
        if (task.isSuccessful) {
            tokenTextView.text = task.result
        }
    }
}

물론 위 코드는 공식문서에 친절히 기재 돼 있다. 여기서 받은 토큰을 복사하여, 추후에 cloud message에서 send기능을 이용할때 토큰을 이용 하면 된다.

## 2.Firebase <-> 안드로이드 기기사이에서 알림을 주고 받을 채널 만들어주기

먼저 MyFirebaseMessagingService클래스를 새로 만들어준다, 그리고 FirebaseMessagingService()을 상속한다.  두 함수를 override해준다. 

class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onNewToken(token: String) {
        super.onNewToken(token)
    }

    override fun onMessageReceived(message: RemoteMessage) {
	    super.onMessageReceived(message)
	}

}

또한 manifest에 아래 내용을 <application>안에 추가해준다

<service
  android:name=".MyFirebaseMessagingService"
  android:exported="false">
  <intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT" />
  </intent-filter>
</service>

이제 채널을 만들어줘야한다. 공식문서에 채널을 만드는 방법에 있는 코드를 가져와 사용하면 된다.

 

알림 채널 만들기 및 관리  |  Android 개발자  |  Android Developers

알림 채널 만들기 및 관리 Android 8.0(API 수준 26)부터는 모든 알림을 채널에 할당해야 합니다. 채널마다 채널의 모든 알림에 적용되는 시각적/음향적 동작을 설정할 수 있습니다. 그런 다음 사용자

developer.android.com

private fun createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT)
        channel.description = CHANNEL_DESCRIPTION

        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.createNotificationChannel(channel)
    }
}


companion object {
    private const val CHANNEL_NAME = "Emoji Party"
    private const val CHANNEL_DESCRIPTION = "Emoji Party를 위한 채널"
    private const val CHANNEL_ID = "채널 ID"
}

채널을 통해서 알림이 들어온다. 채널을 만들고 파이어베이스에서 알림을 보내면 채널이 생성됨을 볼 수 있다. 내 App 정보 -> 알림에 들어가 보면 알 수 있다.

 

## 3. NotificationCompat빌더를 만들어 빌드하기

override fun onMessageReceived(message: RemoteMessage) {
    super.onMessageReceived(message)
    createNotificationChannel() // 채널생성함수 호출
    // 코드작성
}

위 함수를 override하여 메시지가 도착했을 경우의 행동을 정의 해줘야한다. message인자는 파이어 베이스에서 보낸 메시지다. 보내지는 메시지의 key와 vaule값을 통해 값을 받아온다. 

val type = message.data["type"]?.let {
    NotificationType.valueOf(it)
}
val textTitle = message.data["title"]
val body = message.data["body"]

type ?: return

textTitle은 제목, body는 내용을 담아줄 것이다. type은 이 알림이 어떤형태를 띄는 것인지 구분하기 위해 보내준다. 여기서는 일반형, bigtext, custom으로 3가지를 분류한다. 이 타입에 따라 도착하는 메시지의 형태가 다르다. 결과물 미리보기를 참고하면 된다.

만약 여러가지 타입을 대응하지 않는다면 저렇게 type별로 분기시킬 필요가 없지만, 3가지의 타입을 만들어야하기때문에 notify의 두번째 인자로 createNotification을 만들었다. 

with(NotificationManagerCompat.from(this)) {
    // notificationId is a unique int for each notification that you must define
    notify(type.id, "빌더를 빌드하여 여기에 넣는다" ) // 두번째 인자로 빌더가 들어감
}

builder를 만드는것은 간단하다. 공식문서에 있는 코드를 가져오면 된다.

val builder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle(textTitle)
            .setContentText(textContent)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)

위처럼 builder을 만들어주고, 두번째 인자에서 builder.build()를 해주면 된다는 이야기이다. 그렇지만 type별로 분류하여 builder를 만들어지는 과정을 보자.

 

### 타입별로 builder분류하기

private fun createNotification(type: NotificationType?, textTitle:String?, body: String?) : Notification {
        
        // 알림을 누르면 실행될 수 있게 intent를 만들어줌
        val intent = Intent(this,MainActivity::class.java).apply {
            putExtra("notificationType","${type?.title} 타입")
            addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) // 이미 해당 액티비티일때 인텐트가 연결되면 1개만 유지함
        }

        val resultPendingIntent = PendingIntent.getActivity(this,type!!.id,intent, FLAG_UPDATE_CURRENT)



        // 기본 빌더
        val builder =  NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_notifications)
            .setContentTitle(textTitle)
            .setContentText(body)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(resultPendingIntent) // 알림을 누를경우 생기는 인탠트
            .setAutoCancel(true)

        Log.d("createNotification",type?.title.toString())
		
        // 빌더에 type별로 속성을 추가해준다.
        when(type){
            NotificationType.NORMAL -> Unit
            
            // 많은 text가 올 경우
            NotificationType.EXPANDABLE -> {
                builder.setStyle(NotificationCompat.BigTextStyle()
                    .bigText(bigEmoji))
            }
            
            //layout을 통해 custom하기
            NotificationType.CUSTOM -> {
                builder.setStyle(NotificationCompat.DecoratedCustomViewStyle())
                    .setCustomContentView(RemoteViews(packageName,R.layout.view_custom_notification)
                        .apply {
                            setTextViewText(R.id.title, textTitle)
                            setTextViewText(R.id.message, body)
                        })

            }
        }
		
        // build()하여 반환함으로써 notify에서 한번에 사용
        return builder.build()
    }

위에서 소개한거와 같이 type별로 분류하는 것이다. 그리고 인탠트를 연결하여 해당알림 클릭시 액티비티가 열리게 하고, autocancel을 추가하여 클릭하며 알림이 없어지도록 했다.

 

## 4. notify를 통하여 빌더 호출하기

//notify호출하여 알림 실행
with(NotificationManagerCompat.from(this)) {
    // notificationId is a unique int for each notification that you must define
    notify(type.id, createNotification(type,textTitle,body))
}

재정의한 onMessageReceived 함수이다. 아까 본거와 같이 두번째 인자로 방금 만든 createNotification을 통해 빌더를 가져오게 한다. 

 

 

# 마무리

 사실 파이어베이스와 구글 공식문서 있는 코드를 가져와서 조금씩 바꿔주기만 했다. 확실히 코드를 가져와서 활용하는게 중요한거 같다. 내가 이런 코드를 하나하나 다 이해해서 쓰는건 말이 안되는것 같다.

 안스에서도 디버깅 하는 방법을 알았다. 디버그 할 곳을 찍어두고 AVD를 실행시킨 후 안스에서 Run -> Attach Debugger to Android Process를 클릭하면 그곳에서 실행되면 멈춘다. 메시지가 잘 날라오는지 확인할때 유용했다.

 여기에는 적지 않았지만 enum class를 사용해서 NORMAL, EXPANDABLE, CUSTOM의 값을 정의하고 title,id값을 다루니 무척 편리했다.

 처음 SDK추가할때 꽤 애 먹었는데 이글이 유입이 잘 되서 많은 분들이 쉽게 해결했으면 좋겠다.


cloud message SEND 하는곳

 

Method: projects.messages.send  |  Firebase

FirebaseVisionOnDeviceAutoMLImageLabelerOptions

firebase.google.com

파이어베이스 메시지 관련 문서

 

여러 기기에 메시지 전송  |  Firebase Documentation

Join Firebase at Google I/O online May 11-12, 2022. Register now 의견 보내기 여러 기기에 메시지 전송 Firebase 클라우드 메시징은 메시지를 여러 기기로 타겟팅하는 2가지 방법을 제공합니다. 주제 메시징: 특정

firebase.google.com

안드로이드 채널 관련 공식문서

 

알림 채널 만들기 및 관리  |  Android 개발자  |  Android Developers

알림 채널 만들기 및 관리 Android 8.0(API 수준 26)부터는 모든 알림을 채널에 할당해야 합니다. 채널마다 채널의 모든 알림에 적용되는 시각적/음향적 동작을 설정할 수 있습니다. 그런 다음 사용자

developer.android.com

안드로이드 알림 관련 공식문서

 

알림 만들기  |  Android 개발자  |  Android Developers

알림 만들기 알림은 사용 중이 아닌 앱의 이벤트에 관한 짧고 시기적절한 정보를 제공합니다. 이 페이지에서는 Android 4.0(API 레벨 14) 이상의 다양한 기능을 사용하여 알림을 만드는 방법을 설명

developer.android.com

커스텀 알림 관련 공식문서

 

맞춤 알림 레이아웃 만들기  |  Android 개발자  |  Android Developers

맞춤 알림 레이아웃 만들기 여러 Android 버전에서 알림이 가장 잘 보이도록 하려면 항상 표준 알림 템플릿을 사용하여 알림을 만들어야 합니다. 하지만 시스템 템플릿이 요구를 충족하지 않을 경

developer.android.com

 

저작자표시 (새창열림)

'•App > 안드로이드 with Kotlin' 카테고리의 다른 글

[안드로이드&코틀린] 인터파크API이용하여 도서리뷰앱 만들기#1, retrofit,gson, DTO, glide, viewBinding, inflate, layoutinflate, RecyclerView  (0) 2022.04.04
[안드로이드&코틀린] 푸시알림오는 알람 앱 만들기, as, alarmManger, pendingIntent, tag, data class get()예제  (0) 2022.04.03
[안드로이드&코틀린] 웹브라우저 만들기, WebViewSwipeRefreshLayout, ContentLoadingProgressBar, 뒤로가기 버튼 커스텀, imeOptions  (0) 2022.03.28
[안드로이드&코틀린] 녹음기 만들기, Enum, set(value), run{...}, companion object, MediaRecorder, MediaPlayer, 커스텀 View 만들기  (0) 2022.03.25
[안드로이드&코틀린] 뽀모도로 타이머 , SeekBar의 활용, soundPool을 사용한 효과음, 익명객체 활용하기, 문자열포맷팅, "%02d", 슬라이드 바  (0) 2022.03.23
    '•App/안드로이드 with Kotlin' 카테고리의 다른 글
    • [안드로이드&코틀린] 인터파크API이용하여 도서리뷰앱 만들기#1, retrofit,gson, DTO, glide, viewBinding, inflate, layoutinflate, RecyclerView
    • [안드로이드&코틀린] 푸시알림오는 알람 앱 만들기, as, alarmManger, pendingIntent, tag, data class get()예제
    • [안드로이드&코틀린] 웹브라우저 만들기, WebViewSwipeRefreshLayout, ContentLoadingProgressBar, 뒤로가기 버튼 커스텀, imeOptions
    • [안드로이드&코틀린] 녹음기 만들기, Enum, set(value), run{...}, companion object, MediaRecorder, MediaPlayer, 커스텀 View 만들기
    김호쭈
    김호쭈
    공부하고 정리하고 기록하기

    티스토리툴바