티스토리 뷰

728x90

 

 

 

FCM

FCM는 Firebase Cloud Messaging의 약자로, 구글 클라우드 서버를 이용해서 사용자들에게 메시지를 보낼 수 있다.

FCM에서는 디바이스 별로 Token을 부여하는데, 이 Token을 사용해서 특정한 사용자에게 메시지를 보내는 것이다.

 

 

 

출처: https://maejing.tistory.com/

FCM를 통해서 메시지를 전송하는 흐름은 위 그림과 같다.

 

1. 사용자가 앱에 처음 접속할 때 Firebase에서 토큰을 발급해준다.

2. 앱에서는 이 토큰을 서버에 저장한다.

3. 서버에서는 저장된 토큰을 이용해 Firebase 서버에 POST 요청을 보낸다.

4. POST 요청을 받은 Firebase서버는 해당하는 토큰을 가지는 디바이스에게 메시지를 보낸다.

 

 

먼저 토큰을 Firebase 서버에서 받아오는 방법을 알아보자.

 

1. Firebase에 Project 등록 후 설정

1) https://firebase.google.com/?hl=ko 링크에 접속하여 오른쪽 상단 "콘솔로 이동" 버튼을 클릭한다.

 

2) 프로젝트 추가 버튼을 클릭한다.

프로젝트명, Firebase 계정 등을 설정하면 간단히 프로젝트가 생성된다.

 

테스트를 위해 프로젝트 이름을 test로 설정한 화면이다.

3) 생성한 프로젝트에서 Android 아이콘을 클릭한다.

4) 프로젝트의 패키지명을 입력하고, google-services.json을 다운로드 받아 프로젝트 루트 디렉토리에 넣어준다.

 

plugins {
  id("com.google.gms.google-services") version "4.4.0" apply false
}

 

5) 프로젝트 수준의 build.gradle 파일에 위 한줄을 추가한다.

 

plugins {
  id 'com.google.gms.google-services'
}

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

6) 모듈 수준의 build.gradle 파일에 위 세줄을 추가한 후 Sync 버튼을 누른다.

(내 경우에는 gms 버전과 플러그인 버전이 맞지 않아서 오류가 났었다.

플러그인 버전을 업해도 오류가 그대로길래 그냥 gms 버전을 4.3.15로 변경했다.)

 

 

 

2. Token을 받을 수 있도록 코드 구현하기

    implementation 'com.google.firebase:firebase-messaging:21.1.0'

FirebaseMessagingService라는 클래스를 상속받아 토큰을 부여받고 메시지를 받을 수 있다.

이 클래스를 사용하기 위해 모듈 수준의 build.gradle 파일에 위 코드 한줄을 추가한다.

 

class FcmService : FirebaseMessagingService() {

    override fun onNewToken(newToken: String) {
        super.onNewToken(newToken)
    }

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

그리고 FirebaseMessagingService를 상속한 클래스를 생성한다. 클래스명은 FcmService로 지정해주었다.

 

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
    ...
    
        <service android:name=".FcmService"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>
    </application>

이 클래스를 용도에 맞게 사용하기 위해 manifest에 서비스를 등록해야 한다.

인텐트 필터의 액션을 꼭 작성해주는 것이 중요하다. firebase에서 보내는 메시지를 받는다고 명시해주는 것이다.

그리고 메시지를 받는 것은 네트워크 연결이 필요하기 때문에 INTERNET permission도 추가해주었다.

 

 

FirebaseMessagingService의 함수 두개를 오버라이드 했는데, 각각 어떤 역할을 하는지 알아보자.

 

  • onNewToken()

Firebase가 해당 디바이스에 새로운 토큰을 부여할 때마다 자동으로 호출되는 함수다.

토큰은 고정된 값이 아니고, 아래와 같은 경우 토큰이 변경될 수 있으므로 토큰을 주기적으로 갱신해주어야 한다.

- 새 기기에서 앱 복원
- 사용자가 앱 제거/재설치
- 사용자가 앱 데이터 소거

 

  • onMessageReceived()

서버에서 토큰을 이용해 POST 요청 메시지를 보내면, Firebase 서버에서 디바이스로 메시지를 전송한다.

메시지를 받을 때마다 자동으로 호출되는 함수다.

 

 

class FcmService : FirebaseMessagingService() {
    private var token: String
        get() = MyApplication.prefs.getData(TOKEN_KEY, "")
        set(value) {
            MyApplication.prefs.setData(TOKEN_KEY, value)
        }

    override fun onNewToken(newToken: String) {
        super.onNewToken(newToken)
        Log.e(TAG, "onNewToken()")

        token = newToken // 새로운 토큰이 발급될 때마다 SharedPreferences에 갱신
    }

    override fun onMessageReceived(message: RemoteMessage) {
        super.onMessageReceived(message)
        Log.e(TAG, "onMessageReceived()")
        // Notification 발생하는 코드 추가
    }

    companion object {
        private val TAG = FcmService::class.simpleName
    }
}

FcmService를 구현한 전체 코드다.

onNewToken() 함수에는 서버에 토큰을 저장하는 코드가 들어갈 수 있는데,

이 함수는 일반적으로 사용자가 앱을 처음 사용하는 경우 호출되기 때문에 

일단 SharedPreferences에 새로운 토큰을 저장하고, 로그인 시에 이 토큰을 서버에 저장하는 식으로 구현했다.

 

그리고 onMessageReceived에는 Notification을 발생시키는 코드를 추가하면 된다.

Notification 관련한 내용은 이 포스팅을 참고하자. https://thdbs523.tistory.com/373

 

        FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
            if (!task.isSuccessful) {
                Log.e(TAG, "Fetching FCM registration token failed", task.exception)
                return@OnCompleteListener
            }

            token = task.result ?: return@OnCompleteListener

            Log.e(TAG, "token: $token")
            Toast.makeText(this, token, Toast.LENGTH_SHORT).show()
        })

또한 위 코드를 통해 디바이스의 토큰 값을 확인할 수 있다. (FcmService말고 원하는 곳에서 호출 가능)

이 token을 전역 변수로 선언해서 필요한 곳(메시지를 전송)에서 사용하면 된다.

 

 

 

 

이렇게 생성한 토큰을 가지고 디바이스 별로 메시지를 전송할 수 있다.

토큰을 이용해 메시지를 전송하고, 그 메시지를 테스트하는 방법은 아래와 같은 방법들이 있다.

1. Firebase Console에서 메시지를 전송하기

2. Postman으로 Firebase 서버에 POST 요청을 보내기

3. 안드로이드 상에서 Retrofit을 사용해 Firebase 서버에 네트워크 연결을 하기

4. 직접 구축한 서버에서 POST 요청을 보내기

 

1, 2는 정말 테스트를 위한 방법이고 특정 이벤트가 발생할 때마다 메시지를 전송할 수는 없다.

3, 4는 실제 서비스를 구현하는 경우에도 사용할 수 있는데 보통은 가장 마지막 방법을 주로 사용한다.

 

포스팅이 너무 길어져서, 토큰으로 메시지를 전송하는 여러 방법에 대해서는 따로 포스팅을 해야겠다.

 

 

 

참고

https://maejing.tistory.com/m/entry/Android-FCM%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%B4-Push-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0

https://suhwanc.tistory.com/160

https://firebase.google.com/docs/cloud-messaging/android/client?hl=ko 

728x90
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함