【Android】FCM(Firebase Cloud Messaging)を使ってプッシュ通知を実装する


前提

Android Studio 4.1.2
Kotlin 1.3.72
テスト用プロジェクトを作成済み

仕事でAndroid + JavaでFCMを使ったプッシュ通知をやったので、復習と勉強のためにKotlinでやってみます。

目標

Notifications Composerからテストメッセージを送信し通知を受け取る。

Firebase SDKの導入

ほぼ公式ドキュメント通りに行いました。

build.gradle

buildscript {
    ext.kotlin_version = "1.3.72"
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.1.2"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        classpath 'com.google.gms:google-services:4.3.5'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

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


app/build.gradle

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdkVersion 29

    defaultConfig {
        applicationId "com.example.testapplication"
        minSdkVersion 28
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

apply plugin: 'com.google.gms.google-services'

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.2.0'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

    implementation platform('com.google.firebase:firebase-bom:28.0.0')
    implementation 'com.google.firebase:firebase-messaging-ktx'
    implementation 'com.google.firebase:firebase-analytics-ktx'
}


実装

通知チャンネルを作成する

Android 8.0(APIレベル 26)以降に対応する場合は通知チャンネルを作成し、通知を作成する際に通知チャンネルのIDを指定する必要があります。下記コードの場合だと"channel_1"が通知チャンネルのIDになります。

val channel = NotificationChannel(
        "channel_1",
        "Channel1",
        NotificationManager.IMPORTANCE_HIGH)
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)


FirebaseMessagingServiceを継承したサービスを作成する

・onMessageReceived
アプリがフォアグラウンドでメッセージを受信した時に呼び出される処理。
アプリがバックグラウンドでメッセージを受信した時は呼び出されないので注意。

・onNewToken
FCM登録トークンが生成された時に呼び出される処理。

package com.example.testapplication;

import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class MyFirebaseMessagingService : FirebaseMessagingService() {
    companion object {
        private const val TAG = "MyFirebaseMessagingService"
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        Log.d(TAG, "onMessageReceived")

        remoteMessage.notification?.also {
            showNotification(it)
        } ?: Log.w(TAG, "remoteMessage.notification is null")
    }

    private fun showNotification(remoteNotification: RemoteMessage.Notification) {
        val notification = NotificationCompat.Builder(this, "channel_1")
                .setSmallIcon(R.drawable.ic_notification)
                .setContentTitle(remoteNotification.title)
                .setContentText(remoteNotification.body)
                .build()
        val notificationManager = NotificationManagerCompat.from(this)
        notificationManager.notify(0, notification)
    }

    override fun onNewToken(token: String) {
        Log.d(TAG, "Refreshed token: $token")
    }
}


通知アイコンはimageAssetで作成しました。




AndroidManifest.xmlにサービスを追加します。

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


FCM登録トークンを取得する

FCM登録トークンは相手(端末)を指定して通知を送信する時に使用します。

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

    val token = task.result
    Log.d(TAG, "Refreshed token: $token")
})


Notifications Composerからテストメッセージを送信する

Notifications ComposerとはFirebase Consoleから遷移できる、通知を管理できる画面のことです。

Notifications Composer

FCM登録トークンを使ってテストメッセージを送る方法と、通知を作成して送信する方法両方で試し、通知の受信を確認できました。
FCM登録トークンを使ってテストメッセージを送る手順は公式ドキュメントに記載されています。