2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React でのFirebase Realtime Databaseの使い方

Last updated at Posted at 2021-11-11

はじめに

Firebasa Realtime Databaseを使う必要が出てきたので、備忘録として残して置きます。本記事はウェブアプリケーションを想定して説明するので、モバイルなどの方は注意してください。また構築環境がUbuntuなのでMacの人はパッケージマネージャなど適宜読み替えお願いします。今回はデータベースのみの使用であり、フロントエンド側のホスティングについては深くは触れません(ローカルで動けばOKとします。)

環境

Ubuntu20.04
React
TypeScript
create-react-appをベースに構築
yarn

Firebase Realtime Databaseの作成

まずはこちら[1]からFirebaseの公式にアクセス。Chromeを使っているなら既にログインされていると思います。使ってない人はログインしましょう。次にプロジェクトを追加を押し、プロジェクト名を入力します。その後Googleアナリティクスや地域の設定をした後プロジェクトを作成します。左側の構築をクリックした後Realtime Databaseをクリックします。データベースを作成を押し、ロケーションをシンガポール、セキュリティルールをテストモードにします。セキュリティモードは本来ならロックモードがいいですが、とりあえず読み取りや書き込みしたいだけなのでテストモードでいきます。これで作成までは出来ました。

プロジェクトへのアプリの登録

こちら[2]を参考にしてウェブアプリケーションを登録していきます。次にプロジェクトページの上部にあるウェブアイコンをクリックします。アプリケーション名を追加してホスティングを無効に(有効にしても大丈夫です)した後にFirebase SDKの追加なのですが、公式ではyarnでの方法が書かれていませんでした。create-react-appでやりたいので、yarnでやりたい。調べてみると出来そうなのでやっていく。

まずはfirebaseのインストール。公式ではグローバルにインストールしているが、汚したくないのでローカルにインストール。

yarn add firebase

次にFirebase側の方で表示されるFirebase SDKの追加でnpmを使用するにチェックを入れて出てきたスクリプトをコピー。自分の場合はindex.tsxにコピペしたが、場所は好きに変えていいと思います。データベースの取得だけ追加していますので注意してください。

index.tsx
import React from "react";
import ReactDOM from "react-dom";
import { App } from "./App";

import { getDatabase } from "firebase/database";
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
// import { getAnalytics } from "firebase/analytics";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
    apiKey: "AIzaSyCLifYdh2b-V9WzIK1X3cL9gRoI_q5UC24",
    authDomain: "chat-app-86125.firebaseapp.com",
    databaseURL:
        "https://chat-app-86125-default-rtdb.asia-southeast1.firebasedatabase.app",
    projectId: "chat-app-86125",
    storageBucket: "chat-app-86125.appspot.com",
    messagingSenderId: "717771492231",
    appId: "1:717771492231:web:4019216ccf20fc5052e122",
    measurementId: "G-BQCX5GM9PP",
};

// Initialize Firebase
// const app =
initializeApp(firebaseConfig);
// const analytics = getAnalytics(app);
export const db = getDatabase();

ReactDOM.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
    document.getElementById("root")
);

ここまでで設定は完了です。これでもうDBは使用可能になっています。

hostingを有効にした人向け

最初間違えてhostingを有効にしちゃったのでその時やったことも備忘録として書いておきます。色々やったんですが上の設定出来た人は多分要りません。hostingするときがあれば参考にしてください。

Firebase CLIをインストール。何故か名前が違うので注意。

yarn add firebase-tools

ログインをします。グローバルにインストールしてあればyarnは不要です。

yarn firebase login

自動的にブラウザが立ち上がり、ブラウザ側でログインできれば成功です。
次に初期化をします。

yarn firebase init

実行すると色々選択肢が出てきます。今回利用したいのはFirebase Realtime DatabaseなのでDatabaseを選択しましょう。選択するのはSpaseキーで決定がEnterキーなので注意してください。Enterキーを押した後、Please select an optionと聞かれるので、既にプロジェクトを作成しているのでUse an existing projectを選択しましょう。次にSelect a default Firebase project for this directoryと聞かれるので自分のディレクトリと対応させたいアプリケーションを選択しましょう。最後にWhat file should be used for Realtime Database Security Rulesと聞かれますが、デフォルトで大丈夫なのでEnterキーを押してそのまま進みましょう。

最後にデプロイです。

yarn firebase deploy

最後に出てくるURLを押して特にエラーが出てなければおkです。データベースだけが使える状態です。本当はここで色々違うものを選択してホスティングするのだと思います。

実際に確認

次にローカルのReactアプリケーションで取得して確認してみましょう。ルーティングや細かいものは説明しません。React側で表示されているページコンポネートに下記のように記載します。

import { child, get, ref, set, getDatabase } from "firebase/database";
import { useState, VFC } from "react";
import { db } from "../../index";

export const FireBasePage1: VFC = () => {
    const [userName, setUserName] = useState("");
    const dbRef = ref(getDatabase());
    get(child(dbRef, `users`))
        .then((snapshot) => {
            if (snapshot.exists()) {
                console.log(snapshot.val());
            } else {
                console.log("No data available");
            }
        })
        .catch((error) => {
            console.error(error);
        });
    return (
        <>
            <div>Page1</div>
            <input
                onChange={(e) => setUserName(e.target.value)}
                placeholder="ユーザー名を入力してください"
            ></input>
            <button
                onClick={() => {
                    set(ref(db, "users/"), {
                        username: userName,
                    });
                }}
            >
                データ追加
            </button>
        </>
    );
};

yarn startでサーバーをたてたあとボタンを押すことでデータベースにデータが追加できます。Firebaseのデータ側でも確認できますし、コンソールにも取得したデータを出力しています。

Realtime Databaseの仕組み

フロント側でイベントリスナーを一度アタッチしてしまえばあとはデータベースに変更があった時に自動的に、フロントで設定したコードを実行してくれる。引数としてデータベースへの参照が必要になり、クエリなども使用可能。よく使う機能を簡単に紹介する。

onValue

DBに何かしらの変更があったらイベントリスナーが反応してくれる。一番簡単だが、削除も編集も追加もすべて反応するので実用上はほかのリスナーを使うことが多いかも。snapshot.val()で値を見ることが出来る。

onValue(query(chatQuery), (snapshot) => {
      const newChatData = convertChatData(snapshot.val());
      dispatch(setChatData(newChatData));
    });

getDatabase()

データベースへを返す関数。初期化した後は引数がなくても勝手に返してくれる。

 const db: Database = getDatabase();

ref()

データベースの特定の部分への参照を返す関数。あくまで参照するだけで操作はしない。この参照を利用している限り、そこにあるデータしか基本的にはいじれない。

const chatRef: DatabaseReference = ref(db, "chats");

query()

参照とクエリを引数にとって参照に対してどのような操作をするかを決定する。返り値を参照のように扱うことで、参照に対してここで決めた操作が可能。ただこの方法だとその参照に対して毎回この操作しか出来ないので他の良い方法がないか模索中。

 const chatQuery: Query = query(
    chatRef,
    orderByChild("order"),
    limitToLast(FETCH_CHAT_NUM)
  );

push()

データの追加で使う。しかし、一意な文字列のキーが親プロパティとして保存されるのでフロントエンド側でデータを加工しないと使いにくい。そもそもidを自動生成してくれないのめんどくさすぎる。

おわりに

DBだけの設定なら非常に簡単ですね。

参考文献

[1]:Firebase
[2]:Firebase を JavaScript プロジェクトに追加する
[3]:ウェブでのデータの読み取りと書き込み

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?