search
LoginSignup
1
Help us understand the problem. What are the problem?

posted at

NCMBのFlutter SDKを使ってプッシュ通知を送信する(Android編)

NCMBのコミュニティSDK(公式サポートは提供されていません)としてFlutter向けのSDKを提供しています。Flutter SDKはiOS/Androidはもちろんのこと、Webなどでも利用できます。つまりスマートフォンネイティブの機能は提供していません。

NCMBのプッシュ通知機能は数多くの方に使われている機能でもあり、今回はFlutter SDKを使ってどうプッシュ通知機能を使えば良いのかを紹介します。まずはAndroid編です。

ncmb | Dart Package

利用するライブラリ

上述の通り、Flutter SDKにはネイティブ機能がありませんので、プッシュ通知で利用するデバイストークンを取得する機能がありません。そこで下記のライブラリを使います。

セットアップ

Androidの場合はFirebaseにてプロジェクトを作成します。そして、Cloud Messagingを有効にしてAndroid用の設定をウィザードで進めます。最終的にgoogle-services.jsonがダウンロードできます。

3522ee8e-dc4a-4a18-8cbb-bf8815d18957.jpeg

また、プロジェクトの設定で新しい秘密鍵を作成、ダウンロードします。

ae358af8-fb87-465f-9e4d-30c58b3aceb7.jpg

この秘密鍵はNCMBの管理画面にてAndroid用プッシュ通知のファイルとしてアップロードしてください。

image.png

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クラスにデータが追加されています。

bcf1b581-f92d-453b-83c1-7858e9b13f23.jpeg

これでプッシュ通知の送信準備が整いました。

プッシュ通知を送信する

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?.titlemessage.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));
	}
});

screen.png

そして、ローカル通知を開いた時には 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を利用できます。ぜひ活用してください。

mBaaSでサーバー開発不要! | ニフクラ mobile backend

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
1
Help us understand the problem. What are the problem?