Raspberry Pi で温湿度&気圧を計測し Firebase × Vue.js (&vue-chartjs) で可視化

#はじめに
Firebase と Vue.js で簡単に Web アプリを公開できると聞き、かねてから興味があったので、勉強のために自分で何か作ってみようと画策。目的が勉強なので、あとで忘れてしまっても思い出せるよう事細かに記載します。同様のことで苦戦している人の助けになれば幸いです。

#全体像
1. ラズパイに温湿度気圧センサ (BME280) を接続。通信は I2C。Python スクリプトで I2C 通信し、温湿度＆気圧を取得
- 取得した温湿度＆気圧情報を Firebase の Firestore (DB) へ add
- Firestore 内のセンサデータを読み取りグラフ作成するページを、Vue.js および Vue-chart.js で作成
- そのページを Firebase hosting で公開
![全体図.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186524/c867a436-7f38-71a6-9b53-436bb9b6588d.png)


以降、各手順を詳細に説明する。



#0. 使用したもの
- Raspberry Pi Zero WH
- Google Firebase
- MacBook Pro 
- [BME280](https://www.amazon.co.jp/KeeYees-BME280搭載-気圧センサーモジュール-Arduino対応-Raspberry/dp/B07QXPJ8XP?pd_rd_w=dgkID&pf_rd_p=a28628f5-988a-4aa7-872f-ab927efba09c&pf_rd_r=9XQEEDRFXKZHEJ8FE9E5&pd_rd_r=dc59cbc3-32fc-4e4d-ad41-b1be500b5b4f&pd_rd_wg=7YpXo&pd_rd_i=B07QXPJ8XP&ref_=pd_bap_d_rp_1_1_i) (温湿度気圧センサ)
    - 今回は Amazon で KeeYees のものを購入。3 個で 1,800 円。
- [ジャンパー線](https://www.amazon.co.jp/フルスイング-3-02-0851-1-ブレッドボード・ジャンパーワイヤー（メス-メス）（20cm）40本/dp/B01A4DDUTA?pd_rd_w=bJrra&pf_rd_p=a28628f5-988a-4aa7-872f-ab927efba09c&pf_rd_r=57YXHZXD4HXY7WNWTD6Q&pd_rd_r=1fddc684-5a82-4e0e-a30e-05b465fbd34e&pd_rd_wg=pvNEr&pd_rd_i=B01A4DDUTA&ref_=pd_bap_d_rp_1_1_i)
    - ラズパイとセンサの接続用

#1. ラズパイで温湿度＆気圧を取得する
##ラズパイセットアップ
OS インストールから SSH 接続までを以前、別の記事でまとめたので、下記を参照。
https://qiita.com/wakodai/items/87580d1471d8894169e2

##センサの接続
電源、GND、それから I2C の SCL(クロック)、SDA(データ)を接続するだけ。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186524/f97280d3-be1f-cf33-7012-428e5e00a36a.png"> <img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186524/a72117dd-525b-529f-f205-2d38204ab3da.png">




## 気温、気圧、湿度の読み取り
### I2C 有効化
I2Cはシリアル通信のプロトコルの 1 つである。ラズパイに標準で備わっている。今回使用するセンサにも備わっている。のでこれでセンサとラズパイは通信し、ラズパイは温湿度気圧情報を取得する。
>I2C（アイ・スクエアド・シー、アイ・アイ・シー）はフィリップス社で開発されたシリアルバスである。低速な周辺機器をマザーボードへ接続したり、組み込みシステム、携帯電話などで使われている。

ラズパイに SSH でログインし、

```bash:ラズパイ側で実施
$ sudo raspi-config
```
で設定画面を開き、画面に従い I2C 有効化

### Python スクリプト
センサから値を取得する Python スクリプトを作成する。まずはじめに、Python で I2C バスを使うために smbus ライブラリをインストールする。smbus とはなんぞやだが、smbus もシリアル通信プロトコルの 1 つで I2C をベースにしているため、Python 用に用意されている smbus ライブラリが使える、ということらしい。

```bash:ラズパイ側で実施
$ sudo pip3 install smbus2
```
でインストール。

※ 後述する firestore へデータを飛ばす部分のコードも含まれています。

```python:hoge.py
#coding: utf-8

from smbus2 import SMBus
import time
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
import datetime

# 後述する firestore へデータを add するための権限ファイル (json) を読み込む
# json ファイルのパスを絶対パスにしないと cron で動かない部分でハマったので注意
cred = credentials.Certificate("/home/pi/Python/******.json")
firebase_admin.initialize_app(cred)
db = firestore.client()

bus_number  = 1
i2c_address = 0x76

bus = SMBus(bus_number)

digT = []
digP = []
digH = []

t_fine = 0.0

def writeReg(reg_address, data):
	bus.write_byte_data(i2c_address,reg_address,data)

def get_calib_param():
	calib = []

	for i in range (0x88,0x88+24):
		calib.append(bus.read_byte_data(i2c_address,i))
	calib.append(bus.read_byte_data(i2c_address,0xA1))
	for i in range (0xE1,0xE1+7):
		calib.append(bus.read_byte_data(i2c_address,i))

	digT.append((calib[1] << 8) | calib[0])
	digT.append((calib[3] << 8) | calib[2])
	digT.append((calib[5] << 8) | calib[4])
	digP.append((calib[7] << 8) | calib[6])
	digP.append((calib[9] << 8) | calib[8])
	digP.append((calib[11]<< 8) | calib[10])
	digP.append((calib[13]<< 8) | calib[12])
	digP.append((calib[15]<< 8) | calib[14])
	digP.append((calib[17]<< 8) | calib[16])
	digP.append((calib[19]<< 8) | calib[18])
	digP.append((calib[21]<< 8) | calib[20])
	digP.append((calib[23]<< 8) | calib[22])
	digH.append( calib[24] )
	digH.append((calib[26]<< 8) | calib[25])
	digH.append( calib[27] )
	digH.append((calib[28]<< 4) | (0x0F & calib[29]))
	digH.append((calib[30]<< 4) | ((calib[29] >> 4) & 0x0F))
	digH.append( calib[31] )

	for i in range(1,2):
		if digT[i] & 0x8000:
			digT[i] = (-digT[i] ^ 0xFFFF) + 1

	for i in range(1,8):
		if digP[i] & 0x8000:
			digP[i] = (-digP[i] ^ 0xFFFF) + 1

	for i in range(0,6):
		if digH[i] & 0x8000:
			digH[i] = (-digH[i] ^ 0xFFFF) + 1

def readData():
	pressure = 0.0
	pressure_hpa = 0.0
	temperature = 0.0
	humidity = 0.0
	data = []
	for i in range (0xF7, 0xF7+8):
		data.append(bus.read_byte_data(i2c_address,i))
	pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
	temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
	hum_raw  = (data[6] << 8)  |  data[7]

	temperature = compensate_T(temp_raw)
	pressure = compensate_P(pres_raw)
	pressure_hpa = pressure / 100
	humidity = compensate_H(hum_raw)

	sensorData = {
		u'temperature': temperature,
		u'pressure': pressure_hpa,
		u'humidity': humidity,
		u'datetime': datetime.datetime.utcnow()
	}
	db.collection(u'raspi_temperature').add(sensorData)

def compensate_P(adc_P):
	global  t_fine
	pressure = 0.0

	v1 = (t_fine / 2.0) - 64000.0
	v2 = (((v1 / 4.0) * (v1 / 4.0)) / 2048) * digP[5]
	v2 = v2 + ((v1 * digP[4]) * 2.0)
	v2 = (v2 / 4.0) + (digP[3] * 65536.0)
	v1 = (((digP[2] * (((v1 / 4.0) * (v1 / 4.0)) / 8192)) / 8)  + ((digP[1] * v1) / 2.0)) / 262144
	v1 = ((32768 + v1) * digP[0]) / 32768

	if v1 == 0:
		return 0
	pressure = ((1048576 - adc_P) - (v2 / 4096)) * 3125
	if pressure < 0x80000000:
		pressure = (pressure * 2.0) / v1
	else:
		pressure = (pressure / v1) * 2
	v1 = (digP[8] * (((pressure / 8.0) * (pressure / 8.0)) / 8192.0)) / 4096
	v2 = ((pressure / 4.0) * digP[7]) / 8192.0
	pressure = pressure + ((v1 + v2 + digP[6]) / 16.0)
	print("pressure : %7.2f hPa" % (pressure/100))

	return pressure

def compensate_T(adc_T):
	global t_fine
	v1 = (adc_T / 16384.0 - digT[0] / 1024.0) * digT[1]
	v2 = (adc_T / 131072.0 - digT[0] / 8192.0) * (adc_T / 131072.0 - digT[0] / 8192.0) * digT[2]
	t_fine = v1 + v2
	temperature = t_fine / 5120.0
	print ("temp : %-6.2f degC" % temperature)

	return temperature

def compensate_H(adc_H):
	global t_fine
	var_h = t_fine - 76800.0
	if var_h != 0:
		var_h = (adc_H - (digH[3] * 64.0 + digH[4]/16384.0 * var_h)) * (digH[1] / 65536.0 * (1.0 + digH[5] / 67108864.0 * var_h * (1.0 + digH[2] / 67108864.0 * var_h)))
	else:
		return 0
	var_h = var_h * (1.0 - digH[0] * var_h / 524288.0)
	if var_h > 100.0:
		var_h = 100.0
	elif var_h < 0.0:
		var_h = 0.0
	print ("hum : %6.2f ％" % (var_h))

	return var_h

def setup():
	osrs_t = 1			#Temperature oversampling x 1
	osrs_p = 1			#Pressure oversampling x 1
	osrs_h = 1			#Humidity oversampling x 1
	mode   = 3			#Normal mode
	t_sb   = 5			#Tstandby 1000ms
	filter = 0			#Filter off
	spi3w_en = 0			#3-wire SPI Disable

	ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode
	config_reg    = (t_sb << 5) | (filter << 2) | spi3w_en
	ctrl_hum_reg  = osrs_h

	writeReg(0xF2,ctrl_hum_reg)
	writeReg(0xF4,ctrl_meas_reg)
	writeReg(0xF5,config_reg)


setup()
get_calib_param()


if __name__ == '__main__':
	try:
		readData()

	except KeyboardInterrupt:
		pass

```


raspi-firestore.py を実行し温度等コンソールに表示されればここまでOK

# 2. センサデータを firestore へ飛ばす
##Firebase の準備
公式ガイドは下記。
https://firebase.google.com/docs/firestore/quickstart?hl=ja

以降、今回自分で実施した手順を記す。

### Firebase プロジェクト作成
- Firebase の[コンソール](https://console.firebase.google.com/?hl=ja)に飛び、まずはプロジェクトを作成（プロジェクト名を命名）する。
    - →何でも良い。今回は「Raspi-iot」とした。
- プランの選択
    - 今回は Spark プラン（無料）にした。
    - Blaze（従量制）との違いは Google Cloud Platform で拡張できるか否か
- Googleアナリティクスの有効/無効を設定
    - →今回はとりあえず有効
- 本番環境 or テストモード
    - →今回はテストモード
- リージョン
    - →特にこだわりはないが近くがいいと思ったので asia-northeast1(東京)




## ラズパイ側の準備
ここまでで、ラズパイでセンサから温湿度＆気温を取得できるようになっているので、その値を Firestore へ飛ばすための準備をする

### Firebase Admin SDK (firebase_admin) のインストール
Firebase Admin SDK についての公式アナウンスは下記を参照。
https://developers-jp.googleblog.com/2017/05/bringing-firebase-admin-to-python.html
以下、理解のためにざっくり書くと、
Firebase Admin SDK とは、(今回のケースでは)ラズパイに Firestore へデータを add する権限を持たせ、かつ add する命令を、Python スクリプトで記述できるようにするためのもの。という理解。

### ラズパイへ Python3.6.11 のインストール
- まずもって、firebase_admin はそもそも python 3.5 以上が必須らしいので、python 3.x 系をインストールする（condaやpyenv環境も考えたが今回はやらない）。
- 後述するが 3.7 以上は openssl も VerUP しないといけなくなるので、3.6 系の Latest なバージョン (3.6.11) とした

ソースを落としてきてコンパイルすることになるのだが、まず先に、コンパイルに必要になるライブラリ `libffi-dev` `libssl-dev` `openssl` をインストールしておく。

```bash:ラズパイ側で実施
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install libffi-dev libssl-dev openssl
```

次にソースコードのダウンロード（任意の場所でOK）

```bash:ラズパイ側で実施
$ wget https://www.python.org/ftp/python/3.6.11/Python-3.6.11.tgz
```
コンパイルしていきます。

```bash:ラズパイ側で実施
$ tar zxvf Python-3.6.11.tgz
$ cd Python-3.6.11
$ ./configure
$ make
$ sudo make install
```
エラー無くインストールできたかどうか、バージョンを確認します。

```bash:ラズパイ側で実施
$ python3 -V
Python 3.6.11
```
3.6.11 になっていれば OK。
次にいよいよ `firebase_admin` のインストールだが、`python` コマンドで`python3` が実行されるようにしておかないと `firebase_admin` インストールに失敗する。下記のようにエイリアスを修正して `python` コマンドで `python3` が実行されるようにする

```bash:ラズパイ側で実施
$ ls -l /usr/bin/python
lrwxrwxrwx 1 root root 9  3月 28  2015 /usr/bin/python -> python2.7 
#↑python コマンドが python2.7 に紐付いている

#↓今回インストールした python3 に python コマンドを紐付ける (python３ がどこにあるかは which python3 で検索)
$ ln -s /usr/local/bin/python3 /usr/local/bin/python
```

pip3 を upgrade しておく

```bash:ラズパイ側で実施
sudo pip3 install --upgrade pip   #  -> pip3がv18.1からv20.1.1になった
```


pip3 で firebase_admin をインストールする

```bash:ラズパイ側で実施
$ sudo pip3 install firebase_admin
```
grpcioライブラリのインストールからなかなか先に進まない。。。

```bash:ラズパイ側で実施
$ sudo pip3 install firebase_admin
〜（中略）〜
Using legacy setup.py install for grpcio, since package 'wheel' is not installed.
Using legacy setup.py install for msgpack, since package 'wheel' is not installed.
Installing collected packages: certifi, urllib3, idna, chardet, requests, six, protobuf, cachetools, pyasn1, pyasn1-modules, rsa, google-auth, pytz, googleapis-common-protos, grpcio, google-api-core, msgpack, cachecontrol, google-cloud-core, google-cloud-firestore, httplib2, uritemplate, google-auth-httplib2, google-api-python-client, google-resumable-media, google-cloud-storage, firebase-admin
    Running setup.py install for grpcio ... \
```
固まっているのかと不安になるが、ソースからビルドする必要があるので非常に時間がかかるとの情報を得る。とりあえず待ってみる。

5時間くらいかかったが無事完了


### cron で定期実行
作成した python スクリプト（上述の hoge.py)を cron で定期実行することで定期的にセンサデータを firestore へ addする


# 3. Vue.js でセンサ情報をグラフにして表示するページを作成
基本的な事を確認
- Vue.js とは、JavaScript のフレームワークの 1 種
- JavaScript とはプログラミング言語
- 実質的に、私たちがブラウジングで体験できることのすべては、ブラウザの中で使われている JavaScript の処理によるもの
- そして、フレームワークとは、プログラミングにおいてアプリケーションプログラム等に必要な一般的な機能を、あらかじめ別に実装し、提供されているもの。開発者はそれを使うだけで済み、自分でわざわざ作らなくて良いので、ラクできる

→つまり、かなり乱暴ですが Vue.js を使うとウェブページが簡単につくれるということですね

## Node.js 環境の準備
- Vue.js で作ったグラフ表示ページを Firebase Hosting で公開したいわけで、つまり、Vue.js で作ったページはサーバサイドで実行させたい
- しかし前述のとおり Javascript はブラウザ側で実行されるプログラム
- しかしサーバサイドで実行させたい
- しかも、開発はローカル環境(Mac)でやりたい。
- そこで登場するのが、Node.js
- Node.js は Webブラウザ以外（例えばサーバサイド）で JavaScript を実行するための環境の 1 つ
    - なぜサーバサイドで、、、、はあとで書く
- Mac に Node.js 環境を構築すると、サーバサイドで動く Javascript をローカル(Mac)で開発でき、さらにはサーバで実行させることまで Mac の中で模擬でき、開発がはかどる
- ローカルでの開発が終わったら後述する `firebase deploy` コマンド一発で Firebase にホスティングできる。
- Node.js の世界では、開発が活発なのでアップデートが激しく、バージョンがすぐ変わると言うシチュエーションが頻繁に起こる
- そうなると、Node.jsのバージョン管理を行ってくれるツールがあると便利である。
- Node.js のバージョン管理ツールの １ つに nodebrew というものがある。今回はそれをインストールし、それ(nodebrew)を使って Node.js をインストールする

と、言うことかと思う。。。


### nodebrew のインストール

```
$ brew install nodebrew
```
nodebrew が使えるようになった

### Node.jsのインストール（安定版）
```
$ nodebrew install-binary stable
```

下記のようにフォルダがないと怒られたら、、、（私は怒られた）

```bash
Warning: Failed to create the file
Warning: /Users/wakoudaisuke/.nodebrew/src/v14.5.0/node-v14.5.0-darwin-x64.tar.
```

フォルダを作っておいてあげればよい

```
$ mkdir -p ~/.nodebrew/src   # (-pはサブフォルダまで作る）
```
フォルダを作ったらもう一度 `$ nodebrew install-binary stable` を実行

Node.js のインストールに成功したら、以下のコマンドで、インストールされている Node.js のバージョンが一覧できるので、確認する

```
$ nodebrew ls
v14.5.0

current: none
```

インストール直後は `current: none` となっているため、必要なバージョン（ここでは１バージョンしかないが、複数バージョンインストールされている場合は複数出てくる）を決め、有効化する。

```
$ nodebrew use v14.5.0
```
もう一度 `nodebrew ls` を試すと

```
$ nodebrew ls
v14.5.0

current: v14.5.0
```

v14.5.0 が設定されました。

### 環境パスを通す
nodeが使えるように環境パスを通します。
bashの場合は以下。

```
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
```
bash以外で使いたいときは各シェルの適したファイルに追記します。
なんと macOS X 10.15 Catalina からは zsh がデフォルトになったので、zsh では以下になります。

```
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zprofile
```
追記した後、ターミナルを再起動。
もしくは `source` コマンドで環境パスを読み込む。

最後に node が使えるか確認

```
$ node -v
v14.5.0
```

ここで v14.5.0 と表示されればインストール完了。

npmも使えるようになる。

```
$ npm -v
6.14.5
```

## vue-cli の準備
vue-cli とは、
- vue.js で開発を行うにあたり必要な前準備を支援してくれるツール
- CLI とは Command Line Interface の略なので、つまり、コマンドラインでそれをやる
- 開発はプロジェクトという単位で行う
- vue-cli を使ってプロジェクトの作成を行う際、プロジェクトで利用する機能のインストールも一緒に行うことができる。質問に答える形で選択し、インストールをしてくれる。

以下、手順

npm で vue-cli をインストール

```bash
$ npm install -g @vue/cli
```
vue-cli には 2.x 系と 3.x 系があるらしい。
2.x 系は `$ npm install -g vue-cli`、3.x 系は `$npm install -g @vue/cli` となる。パッケージ名が異なる。
ちゃんとインストールされたか、以下で確認

```
$ vue -v
@vue/cli 4.4.6
```
バージョンが返ってくればOK

## プロジェクトの作成
下記コマンドでプロジェクトを作成する

```
$ vue create <プロジェクト名>
```
今回は show-temperature という名前のプロジェクトにするので、下記のようにする。

```bash
$ vue create show-temperature
```
すると cli で各種初期設定が質問形式でなされるので、画面に従い質問に答える形で設定をほどこしていく。今回は全部デフォルトとした。
設定が終われば、show-temperature プロジェクトが完成。同名のディレクトリが作成される。
次のコマンドで、show-temperature プロジェクトをビルドして、ローカル(Mac)に勝手に立ち上げてくれる Web サーバで web ページが実行され、ブラウザで見る事ができるようになる。

```
$ cd ＜プロジェクト名＞
$ npm run serve
```
```bash
 DONE  Compiled successfully in 2704ms             23:39:18

 I  Your application is running here: http://localhost:8080
```
（参考）https://qiita.com/Satachito/items/4a00b402970d657a88f3

ブラウザから http://localhost:8080 にアクセスすることで vue.js のテストページが見れれば成功。




## グラフ描画ページを作成
今回見栄えを意識して vuetify も使ってみる。

```
$ vue add vuetify
〜初期設定を CLI に従って実施。今回はすべてデフォルト〜
```

＊＊＊vue.jsのソースは追って公開＊＊＊


`npm run serve` でローカルで実行しながら開発、修正、を繰り返す。

firebase.js に api 情報をコピペ
main.js に firebase.js の読み込みを追記
参考サイト：https://qiita.com/ryo2132/items/2881d8223eb2ad3050a1


# 4. Firebase Hosting で公開
ローカルでページが完成したら、いよいよ公開の段階に入る。

### Firebase CLI インストールと初期設定
まず、 Mac に Firebase CLI をインストールする。
Firebase CLI は、Firebase プロジェクトの管理、表示、デプロイを行うさまざまなツールを提供してくれる CLI とのこと。
`npm` コマンドで Firebase CLI をインストールできる。

```
$ npm install -g firebase-tools
```

https://qiita.com/rubytomato@github/items/b83caa01fc9c4993f526

今回の例でいうと show-temperature ディレクトリに移動し、まず

```
$ firebase login
```
する。するとブラウザが立ち上がり自分の Google アカウントを選択するページが現れるので、アカウントを選択すると、 `Firebase CLI Login Successful` となる。次に、

```
$ firebase init
```
で、Firebase の初期設定を行う (前述の vue init に似ている）

どのオプションを使うか、画面に従い選択しながら設定する。
　→使わないfunctionとかであとでエラーになると嫌なので、使うやつだけにしたほうがよい。今回は firestore と hosting のみを選択。

既存のプロジェクトを使用するか新規に作成するか聞かれるので既存を選択する。
　→今回は、前述した「Raspi-iot」を使う。既存プロジェクトは表示されるので選択する。


```
(base) Elon:raspi-temperature wakoudaisuke$ firebase init

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

You're about to initialize a Firebase project in this directory:

  /Users/wakoudaisuke/github/firebase/raspi-temperature

? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, th
en Enter to confirm your choices. Firestore: Deploy rules and create indexes for Firestore, Hosting: Co
nfigure and deploy Firebase Hosting sites

=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add, 
but for now we'll just set up a default project.

? Please select an option: Use an existing project
? Select a default Firebase project for this directory: raspi-iot-c076f (Raspi-iot)
i  Using project raspi-iot-c076f (Raspi-iot)

=== Firestore Setup

Firestore Security Rules allow you to define how and when to allow
requests. You can keep these rules in your project directory
and publish them with firebase deploy.

? What file should be used for Firestore Rules? firestore.rules

Firestore indexes allow you to perform complex queries while
maintaining performance that scales with the size of the result
set. You can keep index definitions in your project directory
and publish them with firebase deploy.

? What file should be used for Firestore indexes? firestore.indexes.json

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? public
  //↑ここ注意。vue.jsをデプロイするときは「dist」にする

? Configure as a single-page app (rewrite all urls to /index.html)? Yes　
  //↑ここも注意。vueが吐き出したdist配下にindex.htmlがあればYES。この次にfirebaseが上書きするか聞かれるがそれはNoでいいはず

✔  Wrote public/index.html


i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...
i  Writing gitignore file to .gitignore...

✔  Firebase initialization complete!
```
これで Firebase の初期化が完了。
vuefire もインストールする
vuefire はvue.js の data と firebase をバインディングしてくれるもの。
※vuefire はプロジェクトフォルダでインストールする。かつ、プロジェクトごとにインストールする。っぽい。
(vue create するたびに)


```bash
$ npm install firebase vuefire@next
```




### ビルド
プロジェクトのルートディレクトリ（今回でいうと show-temperature）に移動し、下記コマンドを実行

```
$ npm run build
```
するとビルドされて、dist フォルダに公開用のファイル群が生成される。Mac の dist フォルダを確認してみるとよい。


### デプロイ
生成された dist フォルダ内のファイル群をいよいよデプロイする。
（デプロイとは訳すと「配置」なので、ここでは、作ったページを Firebase Hosting に配置、すなわちインターネットで閲覧できる状態にすること、の意）
プロジェクトのルートフォルダで下記コマンドを実行

```
$ firebase deploy

=== Deploying to 'raspi-iot-c076f'...

i  deploying firestore, hosting
i  firestore: reading indexes from firestore.indexes.json...
i  cloud.firestore: checking firestore.rules for compilation errors...
✔  cloud.firestore: rules file firestore.rules compiled successfully
✔  firestore: deployed indexes in firestore.indexes.json successfully
i  firestore: latest version of firestore.rules already up to date, skipping upload...
i  hosting[raspi-iot-c076f]: beginning deploy...
i  hosting[raspi-iot-c076f]: found 1 files in public
✔  hosting[raspi-iot-c076f]: file upload complete
✔  firestore: released rules firestore.rules to cloud.firestore
i  hosting[raspi-iot-c076f]: finalizing version...
✔  hosting[raspi-iot-c076f]: version finalized
i  hosting[raspi-iot-c076f]: releasing new version...
✔  hosting[raspi-iot-c076f]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/raspi-iot-c076f/overview
Hosting URL: https://raspi-iot-c076f.web.app
```

※`firebase init`をやってないフォルダで`firebase deploy`をやっても`could not locate firebase.json`と言われて怒られる（私は最初怒られた）

実際にデプロイした web アプリがこちら
https://raspi-iot-c076f.web.app




# その他、備忘録
###vuefire で怒られたら

```
export 'default' (imported as 'VueFire') was not found in 'vuefire'
```
と怒れられたら、ここのとおりfirebase.jsを修正する
https://qiita.com/MuggyTea/items/5726019da614ae322dd3

### firestore のルール編集
firestore のアクセス権設定は、ローカルにある firebase.rules を編集する。
web の firebase コンソールからも編集できるが、デプロイするたびにローカルの内容に上書きされる。
ルールの編集は下記を参照
https://firebase.google.com/docs/firestore/security/insecure-rules?hl=ja

>Firebase Admin SDK と Cloud Functions は、引き続きデータベースにアクセスできます


#参考にしたサイト
https://kojimainjp.hatenablog.com/entry/2018/12/26/202942
https://www.ultra-noob.com/blog/2020-03-21-やたら易しいvue-chart-js解説/