ionic 弄り始めて約2ヶ月ですが firebase との組み合わせでうまく動いているので
SPA(Single Page Application) での WebPush 実装方法をまとめてみました。
環境
各環境を整える
-
ionic4
Webテクノロジー(HTML、CSS、JavaScript)を使って、高性能かつ高品質なモバイルとデスクトップアプリケーションをつくるためのオープンソースのUIフレームワーク -
firebase
モバイルおよびWebアプリケーション開発プラットフォーム
Firebase Cloud Messaging(FCM) -
Visual Studio Code
クラウド開発用の強力かつ軽量なコード エディター
サンプルコード
-
ionic-webpush-sample
github リポジトリ -
ionic-webpush-sample.web.app
動作確認用 サンプル
firebase プロジェクト 初期設定
firebase コンソールでプロジェクトを作成し
適当な作業ディレクトリを作り初期化する。
mkdir ionic-webpush-sample
cd ionic-webpush-sample
firebase init
#Functions と Hosting を有効にする
● Functions
● Hosting
#Functions は TypeScript を有効に。
? What language would you like to use to write Cloud Functions?
JavaScript
❯ TypeScript
#後は適当に…
ionic プロジェクト 初期設定
firebase プロジェクト 初期設定したディレクトリで ionic 初期設定をして firebase.json
を一部書き換える。
cd ionic-webpush-sample
ionic start ionicapp blank --type=angular
"hosting": {
"public": "ionicapp/www", <- public ディレクトリではなく ionicapp/www に変更
...
ionic 仮ビルド
ionicapp
ディレクトリをビルドして ionicapp/www
を生成してみる。
cd ionicapp
ionic build
firebase ローカル実行で設定確認
firebase.json
設定が正しく設定されているか確認してみる。
firebase serve
# functions のエラーが表示されるがココでは無視していいです。
http://localhost:5000/
起動後 http://localhost:5000/
にアクセスして Ionic Blank
が表示されていれば
firebase.json
の設定は成功しています。
ココまでの設定で firebase
で ionic
を利用する初期設定が終わりました。
続いて ionic 内で firebase を利用する設定を行います。
ionic に firebase SDK を組み込む
ionic 初期化したディレクトリに移動しえ firebase SDK
を組み込みます。
cd /ionic-webpush-sample/ionicapp
npm install --save firebase
アプリにFirebaseの設定をする。
environments
を修正する。
cofig の値は firebaseコンソール プロジェクトの設定 全般 → マイアプリ → 構成 で 取得することができます。
export const environment = {
production: false,
config:{
apiKey: "AIzaSy...",
authDomain: "ionic-webpush-sample.firebaseapp.com",
databaseURL: "https://ionic-webpush-sample.firebaseio.com",
projectId: "ionic-webpush-sample",
storageBucket: "ionic-webpush-sample.appspot.com",
messagingSenderId: "2986...",
appId: "1:298684318675:web:3..."
}
};
export const environment = {
production: true,
config:{
apiKey: "AIzaSy...",
authDomain: "ionic-webpush-sample.firebaseapp.com",
databaseURL: "https://ionic-webpush-sample.firebaseio.com",
projectId: "ionic-webpush-sample",
storageBucket: "ionic-webpush-sample.appspot.com",
messagingSenderId: "2986...",
appId: "1:298684318675:web:3..."
}
};
アプリ内で firebase SDK 初期化処理を記載する
app.component.ts
を修正して firebase SDK
を初期化する
import * as firebase from 'firebase';
import { environment } from '../environments/environment';
...
initializeApp() {
...
firebase.initializeApp(environment.config);
}
ココまでの設定で ionic アプリ内で firebase sdk を利用できるようになりました。
続いて最低限の ブラウザプッシュ受け取り 処理を書いていきます。
プッシュ通知 受信の為 サービスワーカーの初期設定をする。
app.component.ts
に 処理を追加する。
あわせて assets
ディレクトリに firebase-messaging-sw.js
を追加する。
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
//firebase 初期化
firebase.initializeApp(environment.config);
//プッシュ通知 受信の為のサービスワーカー利用設定
navigator.serviceWorker.register('assets/script/firebase-messaging-sw.js')
.then((registration) => {
firebase.messaging().useServiceWorker(registration);
});
}
YOUR-SENDER-ID
は firebase コンソール で確認する事ができます。
importScripts('https://www.gstatic.com/firebasejs/6.3.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/6.3.1/firebase-messaging.js');
firebase.initializeApp({
'messagingSenderId': 'YOUR-SENDER-ID'
});
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: payload.notification.icon
};
return self.registration.showNotification(notificationTitle,notificationOptions);
});
プッシュ通知パーミッション 確認処理を追加する
home
に 処理を追加する。
# ボタンと トークン表示 欄を追加する
<ion-content>
<ion-item>
<ion-button (click)="clickBtnPushPermission()">パーミッション確認</ion-button>
</ion-item>
<ion-item>
<ion-label>token</ion-label>
<ion-text>{{token}}</ion-text>
</ion-item>
</ion-content>
import * as firebase from 'firebase';
...
export class HomePage {
...
token: string = "";
clickBtnPushPermission() {
//console.log("clickBtnPushPermission");
const _self = this;
firebase.messaging().requestPermission()
.then(function () {
//ユーザー毎のトークンを取得して画面に表示する
firebase.messaging().getToken()
.then(function (token) {
_self.token = token;
})
.catch(function (err) {
console.error('Unable to retrieve refreshed token ', err);
});
})
.catch(function (err) {
console.error('Unable to get permission to notify.', err);
});
}
}
プッシュ通知 許可と トークン取得 確認
ココまでの設定で プッシュ通知 許可と トークン取得ができるようになっている筈なので
ionic ローカル環境を起動して確認してみる。
cd ionicapp
ionic serve
パーミッション確認 ボタンを押すと 確認ダイアログが表示され許可すると トークンが取得され画面に表示される。
ココまでの設定で トークンが取得できた筈。
続いて Cloud Functions
の 関数を定義して 関数経由で プッシュ通知を送る処理を書いていきます。
プッシュ通知送信のための ボタンを 追加する
home
に プッシュ通知送信の為のボタンと処理を追加
<ion-content>
<ion-item>
<ion-button (click)="clickBtnPushPermission()">パーミッション確認</ion-button>
</ion-item>
...
<ion-item>
<ion-button (click)="clickBtnPush()">プッシュ通知 送信</ion-button>
</ion-item>
</ion-content>
clickBtnPush(){
//functions に 定義した関数にパラメータを送って実行する
//TODO token は Realtime Database or Cloud Firestore に保存して
// 他に漏れないように処理する必要がある / プッシュなりすまし等の対策
const value = {
title:"たいとる",
body:"ほんぶん",
icon:"star",
token:this.token
};
const sendNotification = firebase.functions().httpsCallable("send_notification");
sendNotification(value).then(result => {
console.log("sendNotification","result",result);
});
}
プッシュ通知 受信時の処理
app.component.ts
に 受信時に トーストを表示する処理を追加する。
import { ToastController } from '@ionic/angular';
constructor(
...
private toastController: ToastController
) {
...
initializeApp() {
...
//プッシュ通知 受信時の処理
const _self = this;
firebase.messaging().onMessage(function (payload) {
//トーストを表示してみる
_self.showNotificationToast(payload);
});
}
//トーストを表示
async showNotificationToast(payload:any) {
let _self = this;
//payload.notification.icon
const toast = await this.toastController.create({
header: payload.notification.title,
message: payload.notification.body,
position: 'top',
buttons: [
{
side: 'start',
icon: payload.notification.icon,
handler: () => {
console.log(payload);
}
}
]
});
toast.present();
}
WebPushを送信する処理を実装
home
に書いた firebase.functions().httpsCallable
で呼び出させれる関数を functions/src/index.ts
に実装する。
serviceAccountKey.json
は firebase コンソールの プロジェクト設定 で取得できる。
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
/*
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: "https://ionic-webpush-sample.firebaseio.com"
});
*/
admin.initializeApp();
//プッシュ通知するAPI
exports.send_notification = functions.https.onCall((data, context) => {
console.log("data",data);
//プッシュ送信
const value = {
notification: {
title: data.title,
body: data.body
},
webpush: {
headers: {
TTL: "60"
},
notification: {
icon: data.icon,
click_action: data.click_action
}
},
token: data.token
};
return admin.messaging().send(value)
.then((response: any) => {
console.log('Successfully sent message:', response);
return Promise.resolve(response);
})
.catch((error: any) => {
console.log('Error sending message:', error);
return Promise.reject(error);
});
});
functions デプロイ してみる
functions
を デプロイして実行してみる。
cp functions
npm run deploy
cd ../ionicapp
ionic serve
プッシュ通知が動作するか確認
http://localhost:8100/home
にアクセスして トークン取得後に プッシュ通知送信 ボタンを押して見る。 画像のようなトーストが表示されれば成功です。