# はじめに
- プッシュ通知の実装
画面
Firebase ConsoleのCloud Messaging
コンソール上で各項目を設定してプッシュ通知を送信できます。
今回は "テスト メッセージを送信" にて単一端末に対してプッシュ通知を送信します。
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>
プッシュ通知を受信した際の表示
実装
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からでもプッシュ通知を送信するターゲットや送るタイミングを指定すること可能です
ソースコードはこちら