Firebase Cloud Messaging(FCM)を使って AndroidでPush通知を実装します。
Firebase Cloud Messagingとは
Firebase Cloud Messaging(FCM)は、メッセージを無料で確実に配信するためのクロスプラットフォーム メッセージング ソリューションです。以前は Google Cloud Messaging API が使われていたようですが、現在はFCMに移行しています。
Push通知実装の流れ
- Firebaseプロジェクトの作成 - Firebaseコンソール
- Androidアプリでサービスを実装 - Android Studio
- テスト通知 - Firebaseコンソール
- アプリがフォアグラウンド時の通知表示実装 - Android Studio
それでは実装していきましょう。
Firebaseプロジェクトの作成
1 .Firebaseのコンソールから新規にプロジェクトを作成
2 .プロジェクトに名前を付ける
3 .Google アナリティクス
4 .android iconをクリック
5 .Android パッケージ名を入力
Android パッケージ名は、androidアプリのAndroiManifest.xmlで確認できます。
その他の項目は空欄のままで大丈夫です。
6 .google-services.jsonの導入
google-services.jsonとは、今作成したプロジェクトの情報が記述せれているjsonファイルです。
ダウンロードした google-services.json ファイルを Android アプリのappディレクトリー直下に配置します。
7 .Firebase SDK の追加
8 .Firebaseの設定完了
Androidアプリの設定
1 .プロジェクトレベルのbuild.gradleを修正
// 追記 ここから
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.3.13'
}
repositories {
google()
}
}
// ここまで
plugins {
id 'com.android.application' version '7.1.2' apply false
id 'com.android.library' version '7.1.2' apply false
id 'org.jetbrains.kotlin.android' version '1.6.20' apply false
}
task clean(type: Delete) {
delete rootProject.buildDir
}
}
2 .アプリレベルのbuild.gradleを修正
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
// 追記
id 'com.google.gms.google-services'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.example.pushnotificationtest"
minSdk 29
targetSdk 32
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'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.google.firebase:firebase-bom:30.2.0'
implementation 'com.google.firebase:firebase-messaging-ktx:23.0.6'
// 2行追記
implementation 'com.google.firebase:firebase-bom:30.2.0'
implementation 'com.google.firebase:firebase-messaging-ktx:23.0.6'
}
修正したら「Sync now」をクリックします。
3 .FirebaseMessagingServiceを継承したMyFirebaseMessagingServiceクラスを作成
Firebaseのガイド(https://firebase.google.com/docs/cloud-messaging/android/receive) を参考にサービスクラスを作成します。
今回はMainActivityと同じ階層に作成します。
class MyFirebaseMessagingService: FirebaseMessagingService() {
private val TAG = "push notification"
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
Log.d(TAG, "onMessageReceived: " + remoteMessage.data["message"])
}
}
4 .AndroidManifest.xmlにサービスを登録
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.pushnotificationtest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.PushNotificationTest">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 追加 ここから -->
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- 追加 ここまで -->
</application>
</manifest>
5 .MainActivityの修正
FCM token(アプリのアドレス)を取得する為のコードを記述します。
このコードを記述することで、MainActivityが作成されたタイミングでFCM tokenが表示され、自動的にクリップボードにコピーされます。
このtokenは、google keepやメールなどを使いパソコンで利用出来るようにしておいてください。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 追加
updateFCMToken()
}
// 追加
private fun updateFCMToken() {
FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w("FIREBASE", "getInstanceId failed", task.exception)
return@OnCompleteListener
}
val token = task.result
// 以下通知テスト用にFCMトークンを表示、コピーする為の記述
Toast.makeText(baseContext,token,Toast.LENGTH_LONG).show()
val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("text", token)
clipboardManager.setPrimaryClip(clipData)
})
}
}
6 .Androidアプリの設定完了
Androidアプリを実行するとPush通知が受け取れるようになります。
※ただしアプリがフォアグラウンドの時はまだ通知を受信できません。これについては、また後で説明します。
テストメッセージを送信
Firebaseコンソール(https://console.firebase.google.com/) でテスト用の通知メッセージを作成します。
1 .Cloud messageing、send your first messageを順にクリックしてメッセージ作成画面を表示します。
2 .メッセージの送信
通知のタイトル、通知テキストを記述してテストメッセージを送信をクリック。
FCM登録トークンを追加箇所に、先程取得したFCM tokenを貼り付け。
メッセージを送信するとAndroidアプリにPush通知が表示されます。
メッセージは、アプリが起動していない場合、もしくはアプリがバックグラウンドの場合のみに受信します。
アプリがフォアグラウンド時の通知表示実装
androidのpush通知には、2種類あります。
1つはアプリがforeground時の通知、もう1つはアプリがbackground時の通知です。
background時の通知は、OSが自動で受け取ったデータから通知を生成してくれますが、
foreground時の通知は、自分で受けっとた時の処理を書く必要があります。
より詳しく知らたい人は以下のサイトを御覧ください。
https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages
https://note.com/kirimin_chan/n/n04fbabbf17bb
それでは、forground時に通知を受け取れるように実装していきましょう。
1 .MyFirebaseMessagingService classのonMessageReceived関数の編集
以下のコードは受信したデータからtitle, bodyを取得してMainActivityに遷移する通知を作成しています。
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
Log.d(TAG, "onMessageReceived: " + remoteMessage.data["message"])
// 追加 ここから
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT)
val channelId = "Default"
val builder: NotificationCompat.Builder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(remoteMessage.notification!!.title)
.setContentText(remoteMessage.notification!!.body).setAutoCancel(true)
.setContentIntent(pendingIntent)
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(
channelId,
"Default channel",
NotificationManager.IMPORTANCE_DEFAULT
)
manager.createNotificationChannel(channel)
manager.notify(0, builder.build())
// ここまで
}
この記述を追加することで、アプリがforground時でも通知を表示されるようになりました。
またonMessageReceived関数の内容によっては、アプリがforground時にメッセージを受け取った場合にdialogを表示するActivityを起動することでdialogを表示することも可能です。