techa1008

ROCKET NOTE

2018.05.23

Firebaseを利用してプッシュ通知を送る

FirebaseのCloud Messaging (FCM)を利用してプッシュ通知を送ってみます。

Firebaseでwebページを作成する」で作成したプロジェクトを利用します。

まずindex.htmlを以下のように変更します。

SELECT ALL

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta name="robots" content="noindex, nofollow">
	<title>PUSH通知テスト</title>

<!-- Firebase追加箇所 -->

</head>
<body>



<button onclick="selectNotification();">通知を設定する</button>
<button onclick="displayNotification();">トークンを取得</button>
<div id="result"><!--ここにトークンを出力します--></div>
<script>
// JavaScript記述箇所
</script>



</body>
</html>

プロジェクトの詳細ページ(https://console.firebase.google.com/project/プロジェクトID/overview)に移動し、左メニューの「設定(歯車アイコン)」から「プロジェクトの設定」を選択します。

「全般」タブの「アプリ」から「ウェブアプリに Firebase を追加」を選択します。

モーダルウィンドウが立ち上がってコードが表示されるので、コピーして先ほどのHTML内のFirebase追加箇所にペーストします。

次に、JavaScript記述箇所にコードを記述します。

SELECT ALL

// 結果をDOMで表示する用。本題とは無関係!
var result_elem = document.getElementById('result');

// メッセージングオブジェクトの取得
const messaging = firebase.messaging();

// 通知を設定する
function selectNotification(){

	// すでに通知許可済み
	if (Notification.permission == 'granted'){

		result_elem.innerHTML = 'すでに「許可」に設定されています。';

	// すでにブロック済み
	} else if (Notification.permission == 'denied'){

		result_elem.innerHTML = 'すでに「ブロック」に設定されています。';

	// まだ通知の設定をしていない
	} else if (Notification.permission == 'default'){

		// 通知許可のポップアップを表示
		Notification.requestPermission();

	}

}

// 通知する
function displayNotification(){

	// すでに通知許可済み
	if (Notification.permission == 'granted') {

		// 現在の登録トークンの取得
		messaging.getToken()

		// 正常
		.then(function(currentToken){

			// すでにトークンがある
			if (currentToken){

				// トークンを出力
				result_elem.innerHTML = currentToken;

			} else {

				result_elem.innerHTML = 'まだ通知が許可されていないので動きません。';

			}

		// エラー
		}).catch(function(err) {

			result_elem.innerHTML = err;

		});

	// すでにブロック済み
	} else if (Notification.permission == 'denied'){

		result_elem.innerHTML = '通知はブロックされています。通知を受け取るには設定を変更してください。';

	// まだ通知の設定をしていない
	} else if (Notification.permission == 'default'){

		result_elem.innerHTML = 'まず通知の設定をおこなってください。';

	}

}

通知を受け取るためにService Workerを登録する必要があり、firebase-messaging-sw.jsをルート(ドメイン直下)に配置します。中身は以下のようにします。

SELECT ALL

// 自身のスコープにインポート
importScripts('https://www.gstatic.com/firebasejs/5.0.3/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/5.0.3/firebase-messaging.js');

// 初期化
firebase.initializeApp({

	// 送信者 ID
	'messagingSenderId': '先ほどHTMLにFirebaseを追加した箇所の情報をコピペ'

});

// メッセージングオブジェクトの取得
const messaging = firebase.messaging();

Chromeで以下のようなエラーが出る時は、ルートに配置してないことが原因かもしれません。

A bad HTTP response code (404) was received when fetching the script.
Failed to load resource: net::ERR_INVALID_RESPONSE

これでトークンを取得できるので、あとはこのトークンを使ってcURLでプッシュ通知を送ることができます。

Macの場合、ターミナルで以下を実行すればOKです。

SELECT ALL

curl -X POST \
-H "Authorization: key=サーバーキー " \
-H "Content-Type: application/json" \
-d '{
  "notification": {
    "title": "タイトル",
    "body": "本文",
    "icon": "アイコンの画像",
    "click_action": "飛び先のURL"
  },
  "to": "トークン"
}' \
"https://fcm.googleapis.com/fcm/send"

サーバーキーは、先述の「プロジェクトの設定」にある「クラウドメッセージング」タブの「プロジェクト認証情報 」にあります。

PHPで実行する場合は、

を参考に、こんな感じ。

SELECT ALL

/*----------------------------------------------------------------------------------------------------
	設定情報
----------------------------------------------------------------------------------------------------*/

// サーバキー
$key = 'サーバーキー';

// API
$api_url = 'https://fcm.googleapis.com/fcm/send';



/*----------------------------------------------------------------------------------------------------
	POSTから情報を取得
----------------------------------------------------------------------------------------------------*/

// 変数宣言
$token = '';

// トークンを取得
if (isset($_POST['token'])){ $token = $_POST['token']; }

echo "取得したトークン : {$token}";



/*----------------------------------------------------------------------------------------------------
	APIに送信
----------------------------------------------------------------------------------------------------*/

// データ
$data = [
	'to' => $token,
	'notification' => [
		'title' => 'タイトル',
		'body' => '本文',
		'icon' => 'アイコンの画像',
		'click_action' => '飛び先のURL'
	]
];

// ヘッダー
$header = [
	'Authorization: key='.$key,
	'Content-Type: application/json'
];

// cURLでAPIをたたく
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $api_url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
$response = curl_exec($curl);
$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$result = json_decode($body, true);
curl_close($curl);

?>