Blog スタッフブログ

Android システム開発

[Android][Kotlin]FCMプッシュ通知

システム開発担当のTFです。

※Android10対応(他バージョンの場合、細かい部分等が異なる事があります)

やり方

  • Firebaseからアプリを登録する
  • FIrebaseから、google-services.jsonをダウンロードし、アプリに組み込む(app/google-services.json)
  • build.gradleにFCMの設定追加
  • プッシュアイコンの設定(シルエットのみしか表示されないため、シルエットでくりぬいた透過画像と単色設定)
  • AndroidManifest.xmlの設定
  • 現在トークンの取得設定(取得トークンをサーバに送る等)
  • トークン生成のモニタリング(取得トークンをサーバに送る等)

参考

  google-services.jsonとFirebase秘密鍵の設定方法について
  バックグラウンド アプリにテスト メッセージを送信する
  Android アプリでメッセージを受信する
  Android で Firebase Cloud Messaging クライアント アプリを設定する
  Firebase Notificationsのアイコンについて纏めてみた
  Android Push通知のアイコンを作成 + 設定

サンプル

buildscript {
    dependencies {
		// 追加
        classpath 'com.google.gms:google-services:4.3.13'
    }
}
plugins {
    // 追加
    id 'com.google.gms.google-services'
}
dependencies {
	// 追加
    implementation platform('com.google.firebase:firebase-bom:30.3.2')
    implementation 'com.google.firebase:firebase-messaging-ktx:23.0.7'
}

プッシュアイコン設置パスとサイズ

  • app/src/main/res/mipmap-mdpi/push_icon.png    24×24
  • app/src/main/res/mipmap-hdpi/push_icon.png    36×36
  • app/src/main/res/mipmap-xhdpi/push_icon.png   48×48
  • app/src/main/res/mipmap-xxhdpi/push_icon.png   72×72
  • app/src/main/res/mipmap-xxxhdpi/push_icon.png  96×96
<?xml version="1.0" encoding="utf-8"?>
<resources>
	<!-- プッシュ通知のアイコン色 -->
    <color name="push_icon_color">#85879B</color>
</resources>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="test.test.test">

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

    <application
        >
		<!-- プッシュアイコン画像 ->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@mipmap/push_icon" />
		<!-- プッシュアイコン色 ->
        <meta-data android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/push_icon_color" />
			
			
		<!-- トークン生成のモニタリングサービス設定 -->
		<service
            android:name=".MyFirebaseMessagingService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
	</application>

</manifest>
// 現在のトークンの取得
FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
	if (!task.isSuccessful) {
		Log.w("firebase", "Fetching FCM registration token failed", task.exception)
		return@OnCompleteListener
	}

	// Get new FCM registration token
	val token = task.result

	// Log
	Log.d("firebase", token)
})
package test.test.test

import android.util.Log
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class MyFirebaseMessagingService : FirebaseMessagingService() {

    // [START receive_message]
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        // TODO(developer): Handle FCM messages here.
        // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
        Log.d(TAG, "From: ${remoteMessage.from}")

        // Check if message contains a data payload.
        if (remoteMessage.data.isNotEmpty()) {
            Log.d(TAG, "Message data payload: ${remoteMessage.data}")

            if (/* Check if data needs to be processed by long running job */ true) {
                // For long-running tasks (10 seconds or more) use WorkManager.
                //scheduleJob()
            } else {
                // Handle message within 10 seconds
                handleNow()
            }
        }

        // Check if message contains a notification payload.
        remoteMessage.notification?.let {
            Log.d(TAG, "Message Notification Body: ${it.body}")
        }

        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated. See sendNotification method below.
    }
    // [END receive_message]

    // [START on_new_token]
    /**
     * Called if the FCM registration token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the
     * FCM registration token is initially generated so this is where you would retrieve the token.
     */
    override fun onNewToken(token: String) {
        Log.d(TAG, "Refreshed token: $token")

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // FCM registration token to your app server.
        sendRegistrationToServer(token)
    }
    // [END on_new_token]

    /*
    private fun scheduleJob() {
        // [START dispatch_job]
        val work = OneTimeWorkRequest.Builder(MyWorker::class.java)
            .build()
        WorkManager.getInstance(this)
            .beginWith(work)
            .enqueue()
        // [END dispatch_job]
    }
     */

    private fun handleNow() {
        Log.d(TAG, "Short lived task is done.")
    }

    private fun sendRegistrationToServer(token: String?) {
        // TODO: Implement this method to send token to your app server.
        Log.d(TAG, "sendRegistrationTokenToServer($token)")
    }

    companion object {
        private const val TAG = "MyFirebaseMsgService"
    }

    /*
    internal class MyWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) {
        override fun doWork(): Result {
            // TODO(developer): add long running task here.
            return Result.success()
        }
    }
     */
}