はじめに
Firebase Realtime DatabaseをReact使ってみた今日このごろ。
備忘録も兼ねて使い方をまとめておく。
まとめていたら思ったより長くなったので、今回は読み込みまでやる。
今回はReact(クライアント側)の設定だけで、Firebaseのプロジェクトの設定などは割愛する。
※一応やったことはWebUIポチポチしただけ。
TL;DR.
Reactプロジェクト作成
create-react-app
からスタートする。
サクッと用意。
$ npx create-react-app realtime-db-react --template typescript
Firebase周りの設定
プロジェクトの準備
FirebaseCLIを使って設定を進める。
設定は公式のリファレンス を見ながら行う。
また、プロジェクトは作ってある前提とする。
# ログインしていなければログインする
$ npx firebase login
# Firebaseプロジェクト初期化
$ npx firebase init
# 設定した内容は下記の通り
>? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices.
❯◉ Database: Deploy Firebase Realtime Database Rules
? Please select an option:
❯ Use an existing project
? Select a default Firebase project for this directory:
❯ 作成しておいたプロジェクト
# デフォルトのまま
? What file should be used for Database Rules? database.rules.json
✔ Firebase initialization complete!
DBのルール変更
上記手順で作ったままではDBに読み書きできないようになっているので少し修正する。
生成されているdatabase.rules.json
を下記のように修正。
{
"rules": {
// 読むのは誰でも可能
".read": true,
// 書くのは認証済みの場合のみ
".write": "auth != null"
}
}
ルール反映
json変えたではもちろん反映されないので、firebase deploy
コマンドを叩いて反映する。
反映できているかどうかは下記手順で確認できる。
表示されるURLからコンソールを表示
→左カラムにあるDatabase
を選択
→メインカラム上部のプルダウンからRealtime Database
を選択
→ルールタブを表示
$ npx firebase deploy
# ↓が表示されればOK
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/hogehoge/overview
テスト用データ追加
確認用にWebUIからデータ追加しておく。
追加したのは↓の感じ。
{
"sample": {
"key1": "value1",
"key2": "value2"
}
}
実装
Firebase SDKとFirebase Admin SDKのインストール
アプリからFirebaseを使うために必要なライブラリをインストールする。
adminの方は認証がいる場合に必要なのでどちらも入れておく。
$ yarn add firebase firebase-admin
初期化周り
初期化に必要な情報をWebUIから取ってくる。
プロジェクトのページ左カラムにある歯車をクリック
→プロジェクトの設定をクリック
→Settingsページ、全般タブ下側にあるマイアプリにある</>
マークをクリック
→ウェブアプリにFirebaseを追加のページに飛ぶので、お好みの名前を入れて登録をクリック(hostingはお好みで。今回はやらない)
→スクリプトが表示されるので、firebaseConfig
の内容だけコピーする
必要な情報を取れたのでコードを書いていく。
初期化はこれでOK
import firebase from 'firebase/app';
// 認証周りやDB周りで必要なためimportしておく
import 'firebase/auth';
import 'firebase/database';
// コピーしてきたfirebaseConfigそのまま
// 元がvarで宣言されているので、constに変更
const firebaseConfig = {
// コピペ
};
firebase.initializeApp(firebaseConfig);
export {firebase};
データベースに接続する
データのやり取りはfirebase.database.Reference
を通してやり取りされる。
今回は決まったパスのデータを取得したいので、パスを指定した上でメモ化しておく。
// カスタムフックにしておく
const useDatabase = () => {
// 同じパスでは毎回同じ結果が得られるのでmemo化しておく
return useMemo(() => firebase.database().ref('/sample'), []);
};
データを取得する
↑で作ったReferenceを受け取る関数を作成する。
Referenceのイベントをlistenすることでデータを取得できる。
指定したパスのデータに対する更新をすべて検知するにはvalue
を指定すれば良い。
// hooksを使いたいのでカスタムhooksにしておく
const useFetchData = (ref: firebase.database.Reference) => {
const [data, setData] = useState<{ [key: string]: string }>();
useEffect(() => {
// イベントリスナーを追加するにはonを使う
ref.on('value', snapshot => {
// パスに対する全データを含むsnapshotが渡される
// ない場合はnullが変えるので存在をチェックしておく
if (snapshot?.val()) {
setData(snapshot.val());
}
});
return () => {
ref.off();
};
// refの変更に応じて再取得する
}, [ref]);
// データを返却する
return {data};
}
// 実際に呼び出す際はこちらを使う
export const useFetchAllData = () => {
// refを取得して
const ref = useDatabase();
// ref渡してデータを取得する
return useFetchData(ref);
};
Componentからデータ取得する
useFetchAllData
を使ってデータを取ってくるコンポーネントを作成する。
取得したデータはobject形式なので、list形式に変換してから表示する。
import React, {useMemo} from 'react';
import {useFetchAllData} from '../firebase/firebaseDB';
export const ListComponent: React.FC = () => {
// dataを取ってくる
const {data} = useFetchAllData();
// object形式なので使いやすいように{key, value}形式のリストに変換する
// また、データが変わらない限り結果は同じなのでメモ化しておく
const dataList = useMemo(() => Object.entries(data || {}).map(([key, value]) => ({key, value})), [data]);
return <dl>{dataList.map(({key, value}) =>
<React.Fragment key={`${key}${value}`}>
<dt>key: {key}</dt>
<dt>value: {value}</dt>
</React.Fragment>
)}</dl>
};
起動した際に画像のようにデータを表示できればOK。
まとめ
今回はReactでFirebase Realtime Databaseを使ってデータの読み込みができるところまでやった。
最初にも書いたけど思ったより長くなったので今回はここまでにしておく。