Firebase In-App MessagingでカスタムUIのポップアップを表示する
こんにちは、モバイルコースのEtsushiです。
Advent Calendar13日目の記事は「Firebase In-App Messaging」を題材にします。
Firebase In-App Messaging
Firebase In-App Messagingとは、Firebaseのコンソールで入力した情報を元にモバイルアプリ上でポップアップ形式のキャンペーンを表示できる機能です。Android、iOS、およびFlutterのプロジェクトにSDKを入れるだけで表示することが出来ます。
表示形式は、card、 modal、image only、bannerの4つでそれぞれ以下のようなUIになります。
card | modal |
---|---|
image only | banner |
---|---|
Firebaseコンソールでは、キャンペーンとして表示する要素のうち、タイトル、画像、本文、およびボタンアクションなどを設定することでポップアップの見た目を多少カスタマイズできます。
また、配信頻度、ターゲットユーザ、表示トリガー、およびメタデータなど表示条件を設定することにより、配信するキャンペーンの想定ターゲットに絞ってポップアップを表示させることが可能です。
問題点
とても便利なIn-App Messagingですが、問題点もあります。
In-App Messagingでは、Firebaseコンソール上でポップアップの内容を入力するだけでポップアップを表示できますが、文字フォントやサイズ、レイアウトといったポップアップのデザイン要素をカスタマイズして複雑なUIを表示することはできません。また、ポップアップを押下した際の挙動もURLを設定できるのみです。
このため、SDKを入れて表示するだけではアプリデザインとマッチせずアプリの世界観を壊してしまう可能性があり、モバイル側でデザインのカスタマイズをしてあげることが必須となります。
カスタムUIの表示
それではポップアップのUIをカスタムするための実装を行います。
本記事では、Android版の実装を行います。iOSが気になる方はこちらの記事がとても参考になりましたのでご覧ください。
前提
なお、ここでは前提として以下が済んでいるものとして割愛します。
これらの操作が終わっていると、アプリ上でデフォルトのIn-App Messagingのポップアップを表示できると思います。
- Androidプロジェクトの作成
- Firebaseの初期設定
- In-App Messagingライブラリの導入
- GCP上でIn-App Messagingを有効化する
実装
まず、In-App Messagingの表示イベントを受け取った際の動作をカスタマイズするために、FirebaseInAppMessagingDisplay
を継承したクラスを実装します。
本実装では、FirebaseInAppMessagingDisplay
とActivityLifecycleCallbacks
を継承したFirebaseInAppMessagingDisplayImpl
を利用しています。
FirebaseInAppMessagingDisplay
を継承するとdisplayMessage()
の実装が必須となるのでこちらの中身を記述します。
第一引数のInAppMessage
はメッセージの本体でFirebaseコンソール上で設定したタイトルテキストやボタンアクションURLなどを含みます。このメッセージの内容を自作ダイアログなどに注入してカスタムUIの表示を実現します。
第二引数のFirebaseInappMessagingDisplayCallbacks
は、displayMessage()
内で呼び出せるFirebaseへのコールバック群です。中でもcallbacks.impressionDetected()
は、呼び出すことによりFirebaseへユーザがメッセージを受け取ったことを通知します。これにより、表示条件で指定した「キャンペーン中一度のみ表示」などの条件が機能するので忘れず呼び出しましょう。
class InAppMessagingDisplayComponent : FirebaseInAppMessagingDisplayImpl() {
private var listener: InAppMessagingEventListener? = null
interface InAppMessagingEventListener {
fun showModal(title: String?, imageUrl: String?, body: String?, buttonText: String?)
}
override fun displayMessage(
inAppMessage: InAppMessage,
callbacks: FirebaseInAppMessagingDisplayCallbacks
) {
callbacks.impressionDetected()
when (inAppMessage) {
is CardMessage -> {
// カードスタイルの処理
}
is ModalMessage -> {
// モーダルスタイルの処理
val title = inAppMessage.title.text
val imageUrl = inAppMessage.imageData?.imageUrl
val body = inAppMessage.body?.text
val buttonText = inAppMessage.action?.button?.text?.text
listener?.showModal(title, imageUrl, body, buttonText)
}
is ImageOnlyMessage -> {
// 画像のみスタイルの処理
}
is BannerMessage -> {
// バナースタイルの処理
}
}
}
fun registerListener(listener: InAppMessagingEventListener) {
this.listener = listener
}
...
}
次に、FirebaseInAppMessagingのインスタンスにこのInAppMessagingDisplayComponent
をセットしてあげます。これにより、イベントを受け取った際に先ほど実装したdisplayMessage()
が呼び出されるようになるので、In-App Messagingを自由にハンドリングし、カスタムUIで表示できるようになります。
class MainActivity : AppCompatActivity(), InAppMessagingDisplayComponent.InAppMessagingEventListener {
private val displayComponent = InAppMessagingDisplayComponent()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
displayComponent.registerListener(this)
}
override fun onResume() {
super.onResume()
FirebaseInAppMessaging
.getInstance().setMessageDisplayComponent(displayComponent)
}
override fun showModal(title: String?, imageUrl: String?, body: String?, buttonText: String?) {
// モーダルスタイルのカスタムUIを表示
CustomDialog
.create(title, imageUrl, body, buttonText)
.show(supportFragmentManager, "CustomDialog")
}
}
本実装の場合はMainActivity
をイベントリスナーとして登録してMainActivity側でイベントをハンドリングするようにしているのですが、この辺の仕組みは何でも良いです。プロジェクトの方針に合わせた実装にして下さい。
また、例ではモーダルのみハンドリングしています。それ以外は、このままではハンドリングされずデフォルトUIのポップアップすら表示されないので注意して下さい。
実装例は以下の通りです。
例では、Firebaseコンソール上では設定できないタイトルや本文の文字色、サイズ、画像のレイアウトなどをカスタマイズしました。
カスタマイズ前 | カスタマイズ後 |
---|---|
サンプル実装なので、世界観は行方不明ですがカスタムUIが表示できていることがわかります。
おわりに
本記事がIn-App Messagingを利用する際の参考になれば幸いです。
明日はバックエンドのAkinori君の記事です。