Web初心者がfirebaseでPWA入門してみる

# はじめに
キャッチーなタイトルをつけてしまいましたが、これからPWA(Progressive Web Apps)を勉強するための入門編として、というところです。

普段はUnityでゲーム開発をしていて、あまりWebに精通していないので誤りがあったらご指摘ください :bow: 

[第二回: Authorization編](https://qiita.com/tamalign/items/e7c3321c1beb789240d3)

[第三回: ユーザ登録編]
(https://qiita.com/tamalign/items/9f280b4180eeadc560d2)

# PWA(Progressive Web Apps)とは
昨今じわじわと話題になっている(?)ウェブアプリの進化版みたいなものです。

Googleが主導で開発を進めているみたいで、様々なブラウザが対応しています(Chrome, Firefoxなど)。

次期Safariにも一部機能が実装されるみたいです。
(https://www.suzukikenichi.com/blog/pwa-finally-begins-working-in-ios-safari/)

ネイティブみたいなUXをウェブアプリでも提供できるようになるのが大きな特徴です。

## 何ができるようになるの
なぜ畑違いのWebに興味を持ったかというと以下の点が魅力的でした。
#### ・プッシュ通知
いままでiOSではネイティブアプリの特権であったプッシュ通知が使えます・・！

#### ・オフライン利用
PWAではインストール時にキャッシュするデータを指定できます。

#### ・ネイティブアプリのようなUIが利用できる
ここが一番グッときたポイントですが、Webアプリはブラウザから利用するので、ブラウザのデフォルトUIが表示されていていまいち好きじゃありませんでした。

PWAではこれらのUIを非表示にすることが可能です。

またスプラッシュスクリーンの指定も可能で、*起動時にユーザに没入感を与えられる気がします。(適当です)*

**追記: Webに詳しくないので知りませんでしたが、以下のmetaタグを使うとすでに実現できるみたいです**

```html
<!-- android -->
<meta name="mobile-web-app-capable" content="yes">

<!-- iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
```

## PWAに対応するには
基本的には、自分が提供したい機能を実装すればいいみたいです。
今回は以下の2つを使います。

- service-workers.js
    - プッシュ通知やインストール時の挙動を指定するときに利用します。[参考ページ](https://developers.google.com/web/fundamentals/primers/service-workers/)
- manifest.json
    - アイコンやスプラッシュスクリーンの情報などを記述します。[参考ページ](https://developers.google.com/web/fundamentals/web-app-manifest)

# 入門してみる
今回は入門編として、ウェブアプリをローカルにインストールしてスプラッシュスクリーンを出すまでやりたいと思います。

firebaseに関する記事はたくさんあるので自分がつまづいたポイント以外割愛します。

次回の記事ではFirebaseを利用したプッシュ通知に対応します。

## ウェブアプリを用意する
さて、肝心のウェブアプリですが、html, javascriptに明るくないので簡単なものを作ります。

まず完成物はこちら。
https://github.com/tamalign/CheekyCat/tree/Day1

<img width="503" alt="screen-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/79662/e34c40e5-c465-3a83-b843-9486b7f7d3c9.png">


ねこをタップするとfirebaseのRealtime Databaseから文字列を取ってきてランダムに表示します。

画像はいらすとや様からお借りしました。
http://www.irasutoya.com/

### データベースにアクセスする
firebaseのスタートガイドの最初に出てくるこちらですが

```html
<script src="https://www.gstatic.com/firebasejs/4.6.2/firebase.js"></script>
<script>
  // Initialize Firebase
  // TODO: Replace with your project's customized code snippet
  var config = {
    apiKey: "<API_KEY>",
    authDomain: "<PROJECT_ID>.firebaseapp.com",
    databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
    storageBucket: "<BUCKET>.appspot.com",
    messagingSenderId: "<SENDER_ID>",
  };
  firebase.initializeApp(config);
</script>
```
FirebaseHostingを利用するときには以下の一文で済むので素敵です。

```html
<script src="/__/firebase/init.js"></script>
```

さて、Realtime Databaseにアクセスしてみましょう。


```javascript
function FetchMessageData()
{
	var database = firebase.database();
	var message = [];
	database.ref('/cat_message/message').once('value').then(function(snapshot){
		snapshot.forEach(function(childSnapshot) {
			message.push(childSnapshot.val());
		});

		// メッセージの抽選
		var random = Math.floor( Math.random() * message.length );
        // 連続して同じメッセージが抽選されないように
		while (lastSelectedId == random)
		{
			random = Math.floor( Math.random() * message.length );
		}
		lastSelectedId = random;
		message_elm.innerHTML = message[random];
		ChangeCatImage(); // 猫画像のおきかえ
	});
}
```

今回はリアルタイムに読み書きする必要がなかったので、onceメソッドを使用しています。

```javascript

database.ref('/cat_message/message').once('value')
```

取得してきたデータ(JSON形式)を配列(message)に詰め込んで抽選を行います。

連続で同じメッセージが抽選されないようにしています。

*特になにもむずかしいことしていない・・・*

## manifest.jsonを追加する
長くなってしまったので簡単にまとめますが、以下のmanifest.jsonを追加することで`ホーム画面への追加`に対応します。

```manifest.json
{
  "name": "なまいきなねこ", //アプリ名
  "short_name": "なまねこ", //ホームに表示される名前
	"icons": [{ //各種アイコン
    "src": "/images/apple-touch-icon-120x120.png",
    "sizes": "120x120",
    "type": "image/png"
  }, {
    "src": "/images/apple-touch-icon-180x180.png",
    "sizes": "180x180",
    "type": "image/png"
  }, {
    "src": "/images/apple-touch-icon-144x144.png",
    "sizes": "144x144",
    "type": "image/png"
  }, {
    "src": "/images/touch-icon-192x192.png",
    "sizes": "192x192",
    "type": "image/png"
  }],
  "start_url": "/index.html", //起動後のurl
  "display": "standalone", //UI設定
  "orientation": "portrait", //向き
  "gcm_sender_id": "777816644693", //Firebaseからpush通知をするときに利用する
  "background_color": "#2196F3" //スプラッシュスクリーンの背景色
}

```
こちらのリンクの通りにやればスムーズにいきました。
https://developers.google.com/web/fundamentals/web-app-manifest/?hl=ja

## 結果を確認する
![screen.gif](https://qiita-image-store.s3.amazonaws.com/0/79662/8e5fda8d-deb8-471a-7e89-3b0dddbc7d2f.gif)

ホーム画面に追加する際にきちんとアイコンが表示され、名前も指定したものになっていることが確認できました。

また、スプラッシュスクリーンも表示されています。
*ちゃんとアプリっぽい！！！*

# まとめ
今回は簡単なウェブアプリを作成し、manifest.jsonでアイコンとスプラッシュスクリーンを指定しました。

~~次回はfirebaseのRealtime Databaseを利用して`なまいきなねこ`に言葉を教える機能を追加したいと思います。~~
Authorizationが先だと気づきました。