LoginSignup
1
2

More than 3 years have passed since last update.

[Kotlin]Firebase Cloud Messagingの実装

Posted at

 はじめに

  • プッシュ通知の実装

画面

Firebase ConsoleのCloud Messaging

コンソール上で各項目を設定してプッシュ通知を送信できます。

スクリーンショット 2020-05-05 14.10.11.png

今回は "テスト メッセージを送信" にて単一端末に対してプッシュ通知を送信します。
スクリーンショット 2020-05-05 14.10.39.png

Activityは何もない画面

activity_cloud_messaging.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.CloudMessagingActivity">

</androidx.constraintlayout.widget.ConstraintLayout>

プッシュ通知を受信した際の表示

File.jpg

実装

applicationレベルのgradle

build.gradle(app)

dependencies {
   〜

    // Cloud Messaging
    implementation 'com.google.firebase:firebase-messaging:20.1.6'
}

AndroidManifest

AndroidManifest.xml

    <application><!-- new tokenの生成及びメッセージの受信 -->
        <service
            android:name="MyFirebaseMessagingService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

        <!-- デフォルトアイコンの指定 -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@mipmap/ic_launcher_round" />
        <!-- アイコンの色 -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/colorAccent" />
        <!-- Android8以降用のデフォルトチャンネル名 -->
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="@string/default_notification_channel_id" />
        <!-- インスタンスIDの自動生成を禁止にする場合指定 -->
<!--        <meta-data-->
<!--            android:name="firebase_messaging_auto_init_enabled"-->
<!--            android:value="false" />-->
<!--        <meta-data-->
<!--            android:name="firebase_analytics_collection_enabled"-->
<!--            android:value="false" />-->

    </application>

strings.xml

strings.xml
<resources><string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
</resources>

MyFirebaseMessagingService
新しいtokenの生成及び、プッシュ通知を受信した場合、こちらで処理して表示する

MyFirebaseMessagingService.kt
class MyFirebaseMessagingService : FirebaseMessagingService() {

    override fun onNewToken(token: String) {
        Timber.d("Refreshed token: $token")

        sendRegistrationToServer(token)
    }

    private fun sendRegistrationToServer(token: String?) {
        // tokenをserverへ送る
        Timber.d("sendRegistrationTokenToServer($token)")
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)

        // TODO(developer): Handle FCM messages here.
        // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
        Timber.d("From: ${remoteMessage.from}")

        // Check if message contains a notification payload.
        remoteMessage.notification?.body?.let { body ->
            Timber.d("Message Notification Body: $body")
            sendNotification(body)
        }
    }

    // notificationを生成して表示
    private fun sendNotification(messageBody: String) {
        val intent = Intent(this, MainActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT)

        val channelId = getString(R.string.default_notification_channel_id)
        val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val notificationBuilder = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("FCM Message")
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent)

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(channelId,
                "Channel human readable title",
                NotificationManager.IMPORTANCE_DEFAULT)
            notificationManager.createNotificationChannel(channel)
        }

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
    }

}

Activity

CloudMessagingActivity.kt
class CloudMessagingActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_cloud_messaging)

        // インスタンスIDの自動生成を有効化する場合、true
        // AndroidManifestにて自動生成を禁止にしていない場合、不要
//        FirebaseMessaging.getInstance().isAutoInitEnabled = true

        // Current Notificationトークンの取得
        FirebaseInstanceId.getInstance().instanceId
            .addOnCompleteListener(OnCompleteListener { task ->
                if (!task.isSuccessful) {
                    // token取得失敗
                    Timber.d("getInstanceId failed ${task.exception}")
                    return@OnCompleteListener
                }

                // new Instance ID token
                // ここで取得したtokenをテストする際のインスタンスIDとして設定する
                val token = task.result?.token

                val msg = "InstanceID Token: $token"
                Timber.d(msg)
                Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
            })
    }
}

 おわりに

  • 実装する箇所が他のFirabaseの機能に比べて多く、ミスが多くなるかもしれませんが、 それぞれの意味を理解するとミスが減るかと
  • 通常はサーバにtokenを送ってサーバからプッシュ通知を受信するのがベターです
  • サーバ側を実装しなかったとしても今回のようにconsoleから送ることも可能です
  • consoleからでもプッシュ通知を送信するターゲットや送るタイミングを指定すること可能です

ソースコードはこちら

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2