NCMBのコミュニティSDK(公式サポートは提供されていません)としてFlutter向けのSDKを提供しています。Flutter SDKはiOS/Androidはもちろんのこと、Webなどでも利用できます。つまりスマートフォンネイティブの機能は提供していません。
NCMBのプッシュ通知機能は数多くの方に使われている機能でもあり、今回はFlutter SDKを使ってどうプッシュ通知機能を使えば良いのかを紹介します。まずはAndroid編です。
利用するライブラリ
上述の通り、Flutter SDKにはネイティブ機能がありませんので、プッシュ通知で利用するデバイストークンを取得する機能がありません。そこで下記のライブラリを使います。
セットアップ
Androidの場合はFirebaseにてプロジェクトを作成します。そして、Cloud Messagingを有効にしてAndroid用の設定をウィザードで進めます。最終的にgoogle-services.jsonがダウンロードできます。
また、プロジェクトの設定で新しい秘密鍵を作成、ダウンロードします。
この秘密鍵はNCMBの管理画面にてAndroid用プッシュ通知のファイルとしてアップロードしてください。
Flutterアプリの作成
flutter create アプリ名 --org 組織
でアプリを作成します。Androidはコードが入ったフォルダ構成などにも影響するので、指定した方が良さそうです。
Androidの設定
google-services.jsonの配置
android/app/
に先ほどのgoogle-services.jsonを保存します。
android/build.gradleの編集
以下を追加します。最新版を追加するようにしてください。バージョンはAndroid プロジェクトに Firebase を追加する | Firebase Documentationにて確認できます。
dependencies {
// 省略
classpath 'com.google.gms:google-services:4.3.10' // 追加
}
android/app/build.gradleの編集
以下を追記します。
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services' // ← 追加
minSdkVersion を19にします。
minSdkVersion 19
依存ライブラリを追加します。
dependencies {
// 省略
implementation platform('com.google.firebase:firebase-bom:30.1.0') // ← 追加
}
android/app/src/main/AndroidManifest.xmlの編集
applicationタグのandroid:nameを .Application にします。
<application
android:label="pushdemo"
android:name=".Application" <!-- ← ここ -->
android:icon="@mipmap/ic_launcher">
Application.ktの作成
MainActivity.ktがあるフォルダにApplication.ktを作成します。内容は次の通りです。
package jp.moongift.ncmb.pushdemo // パッケージ名は変更してください
import io.flutter.app.FlutterApplication
class Application : FlutterApplication() {
override fun onCreate() {
super.onCreate()
}
}
ic_notification.pngの追加
プッシュ通知用のアイコンファイルを android/app/src/main/res/drawable/ 以下にic_notification.pngとして配置します。
ライブラリの追加
flutter
コマンドでライブラリを追加します。
flutter pub add ncmb
flutter pub add push
flutter pub add flutter_local_notifications
main.dartの編集
ライブラリのインポート
追加したライブラリを読み込みます。
import 'package:push/push.dart';
import 'package:ncmb/ncmb.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
main関数でNCMBを初期化し、その上で FlutterLocalNotificationsPlugin の初期化も行います。
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
void main() {
NCMB("YOUR_APPLICATION_KEY",
"YOUR_CLIENT_KEY");
runApp(const MyApp());
}
デバイストークンの登録
initStateにて新しいデバイストークンを取得した時の処理を追加します。
@override
void initState() {
super.initState();
Push.instance.onNewToken.listen((token) {
setState(() {
_deviceToken = token;
});
saveToken();
});
}
そして saveToken 関数でデバイストークンをNCMBへ保存します。deviceTokenとdeviceTypeは必須です。
void saveToken(String token) async {
try {
var installation = NCMBInstallation();
installation
..set("badge", 0)
..set("deviceToken", token)
..set("deviceType", Platform.isIOS ? "ios" : "android");
await installation.save();
} catch (e) {
debugPrint("エラー ${e.toString()}");
}
}
ちゃんと保存できていれば、NCMBの管理画面でInstallationクラスにデータが追加されています。
これでプッシュ通知の送信準備が整いました。
プッシュ通知を送信する
NCMBの管理画面でプッシュ通知を送信します。送信先としてAndroidを選んでください。
プッシュ通知を受け取る
プッシュ通知を受け取るとイベントが呼ばれるので、initStateで定義します。
@override
void initState() {
super.initState();
Push.instance.onNotificationTap.listen((data) {
// アプリは起動中で、プッシュ通知を開いた場合
});
Push.instance.notificationTapWhichLaunchedAppFromTerminated.then((data) {
// アプリが終了していた場合
if (data == null) {
// アプリ起動時
} else {
// 通知を開いた場合
}
});
Push.instance.onMessage.listen((message) {
// アプリがフォアグラウンド
});
Push.instance.onBackgroundMessage.listen((message) async {
// アプリがバックグラウンド
});
}
messageは次のような内容になっています。dataはこの中のmessage.dataに該当します。dataはプッシュ通知の内容がMapで入っています。
- message.notification(通知オブジェクト)
- message.notification?.title.toString() (通知タイトル)
- message.notification?.body.toString() (通知本文)
- message.data ペイロード
例えばmessage.dataは次のようになります。
{
"com.nifcloud.mbaas.PushId": "UgGJ9dz9KQ7mGmjZ",
"aps": {
"alert": {
"title": "プッシュ通知テスト",
"body": "これはFlutterアプリ向けのプッシュ通知です。"
},
"sound": "default"
}
}
本来はこれでプッシュ通知が表示されるはずなのですが、 message.notification?.title
と message.notification?.body
が null になっているために表示されませんでした。解決策が分かっていないため、代替案としてローカル通知を作成します。
Push.instance.onBackgroundMessage.listen((message) async {
final title = message.data!['title'] as String;
final body = message.data!['message'] as String;
if (Platform.isAndroid) {
const androidPlatformChannelSpecifics = AndroidNotificationDetails(
'remote_notification', 'リモート通知',
channelDescription: 'リモートの通知です',
importance: Importance.max,
priority: Priority.high,
icon: 'ic_notification',
ticker: 'ticker');
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0, title, body, platformChannelSpecifics,
payload: json.encode(message.data));
}
});
そして、ローカル通知を開いた時には Push.instance.onNotificationTap
または Push.instance.notificationTapWhichLaunchedAppFromTerminated
が呼ばれます。
Push.instance.onNotificationTap.listen((data) {
// アプリは起動中で、プッシュ通知を開いた場合
});
Push.instance.notificationTapWhichLaunchedAppFromTerminated.then((data) {
// アプリが終了していた場合
if (data == null) {
// アプリ起動時
} else {
// 通知を開いた場合
}
});
まとめ
Androidのプッシュ通知の場合、Firebaseでプロジェクトを作成することと、build.gradleの修正、Kotlinファイルの作成が必要です。また、なぜかプッシュ通知がそのままでは表示ができなかったため、ローカル通知を組み合わせる必要がありました。この点だけ注意してもらえれば、FlutterアプリでもNCMBを利用できます。ぜひ活用してください。