Firefox (Developer Edition)でW3C Push APIを使ってみる

***FirefoxがWeb Pushに対応したため、本記事の内容の多くは既に古くなっています。Web Pushの(主にサーバサイドでの)扱いについては、別記事「[Web Pushでブラウザにプッシュ通知を送ってみる](http://qiita.com/tomoyukilabs/items/217915676603fda73b0a)」にまとめていますので、そちらをご覧下さい。***

いよいよデスクトップ版Firefoxでも44以降でService Workerとプッシュ通知が使えるようになります。Firefox 42, 43では`about:config`で`dom.serviceWorkers.enabled`と`dom.push.enabled`の両方を`true`にすることで有効化されまます。

基本的にはChromeのPush APIと使い方は同じですので、本記事ではChromeとの違いにフォーカスしします。

# Firefoxのプッシュ通知

ChromeではGoogle Cloud Messaging (GCM)が使われますが、Firefox 42では、Firefox OS (FxOS)でも利用されている[Simple Push](https://developer.mozilla.org/ja/docs/Web/API/Simple_Push_API)が使われることとなります。ただ、FxOSとは異なり、**Application Manifestでのパーミッション等の宣言は不要のようです**(執筆時点)。また、自前でSimple Pushサーバを設置するのではなく、Mozillaが提供するSimple Pushサーバを利用することとなります。

なお、Firefox 43以降では、[Web Push](https://tools.ietf.org/html/draft-ietf-webpush-protocol)に移行しており、以下に記述されている方法ではプッシュ通知を送ることができなくなっていますので、ご注意下さい。その代わり、メッセージ本体を含めたプッシュ通知の受信もできるようになります。

# APIの使い方等について

Push APIをService Worker経由で使う手順自体は、Chromeと全く同じですので、本記事では割愛いたします。「[ChromeでW3C Push APIを使ってみた](http://qiita.com/tomoyukilabs/items/8fffb4280c1914b6aa3d)」を参照して下さい。

Chromeとの挙動の違いとしては、**明示的に通知を許可するかどうかをユーザに確認してからでなければ通知を表示することが出来ない**、という点があります(本来、そうした方がよいでしょう)。具体的には、`Notification.requestPermission(callback)`を呼び出すことによって、ユーザに通知を表示する許可を確認します。(上記の元記事にもサンプルコードに反映しています。)

```js
navigator.serviceWorker.ready.then(checkNotification);

function checkNotification(sw) {
  Notification.requestPermission(function(permission) {
    if(permission !== 'denied')
      sw.pushManager.subscribe().then(function(subscription) { ... });
  });
}
```

![Screen Shot 2015-09-08 at 13.09.05 .png](https://qiita-image-store.s3.amazonaws.com/0/48556/c7d61f50-fe6f-bfa1-fec7-f7b2a63c785a.png)

それ以外は、プッシュ通知をsubscribeしてendpointのURLを取得するという一連の手順は、Chromeと同様です。

# プッシュ通知を発信するには(Firefox 42のみ)

Firefoxでプッシュ通知をsubscribeすると、`subscription.endpoint`の値として、次のようなURLを取得することが出来ます。

```
https://updates.push.services.mozilla.com/push/0123456789VeryLongEndpointURL...0123456789=
```

Chrome (GCM)ではendpointのURLからGCMのURLとRegistration IDを分離する必要がありますが、Firefox (Simple Push)では、**endpointのURLに対してそのままHTTPでPOST(またはPUT)するとプッシュ通知が送信できます**。

このとき、HTTPでサーバに送信するデータ(リクエストボディ)は`version=(番号)`の形式で記述します。この番号は同じendpointに対して送信する際に、**前回送信した時の番号よりも大きな値を指定する必要があります**。また、**最初の番号を0としてしまうと、次回以降はプッシュ通知できなくなるようですので、最初の番号は1以上の整数(自然数)にします**。

`curl`でプッシュ通知を送信する場合は、例えば次のようにします。当然ながら、`version`の値は次回以降大きくする(例えば毎回1ずつ足す)必要があります。

```
curl -d "version=1" https://updates.push.services.mozilla.com/push/0123456789VeryLongEndpointURL...0123456789=
```

このようにすると、Firefoxが起動中で、かつ、通知の表示を許可している場合には、FirefoxのService Workerがプッシュ通知を受信できます。また、Firefox 44以降では、通知の表示と、表示された通知をクリックすることでWebアプリを開いたり開いているウィンドウにフォーカスしたりする機能が利用可能です(若干思った通りに動作しない場合があるようですが)。通知の表示とウィンドウの操作に関する実装方法については、「[ChromeでW3C Push APIを使ってみた](http://qiita.com/tomoyukilabs/items/8fffb4280c1914b6aa3d)」を参照して下さい。

![Screen Shot 2015-09-08 at 13.53.46 .png](https://qiita-image-store.s3.amazonaws.com/0/48556/faa74d7a-5a5f-e849-10d0-811dcbb044e2.png)

但し、ChromeのGCMと同様に、**Firefox 42のSimple Pushではプッシュ通知そのものには対応していますが、プッシュ通知にデータ本体(ペイロード)を付与することができません**ので、ご注意下さい。

ちなみに、Firefoxが起動していない時にプッシュ通知を送信すると、MozillaのSimple Pushのサーバからは「Notification Stored」というレスポンスが返り、Firefox起動時にプッシュ通知が届くようになっているようです。

なお、Firefox 43以降では、[Web Pushのペイロード暗号化](https://tools.ietf.org/html/draft-ietf-webpush-encryption)に対応することでペイロードの送信が可能になります。詳細は動作確認が出来ましたら改めて執筆します。