🫠

Firebaseで基本的なCRUD処理をかく

2025/02/03に公開

はじめに

Firebaseはバックエンドのコードを書かずに実装できるサービスです。
開発でイメージがほしいから最小で一旦作ってみる、や小規模アプリの開発で使えるのかなと思い触ってみました。
Google社が出しているもので、GeminiをFirebase内で活用することもあるみたいですが、基本的な操作だけなので今回は使ってないです。

CRUDのR(読み取り)

const [posts, setPosts] = useState([] as posts[]);
useEffect(() => {
    const postData = collection(db, "posts");
    getDocs(postData).then((snapshot) => {
      setPosts(snapshot.docs.map((doc) => ({ ...doc.data() })));
    });
}, []);

FirebaseのCloudFireStoreはコレクションがテーブル、ドキュメントがレコード、フィールドがカラムの構成になっています。
collection(db, "posts")でpostsコレクションを取得して、その中身をsetPostsで格納しています。ドキュメントの数が多すぎると怖いですが、おそらくたくさんデータを入れる想定のサービスではないかなと思っています。

CRUDのC(作成)

//IDを指定したい時
setDoc(doc(db, "posts", "test"), {
      title: "ドキュメントを追加しました",
      text: "追加",
});

//IDを自動にする時
addDoc(collection(db, "posts"), {
      text: "ドキュメントを追加しました。",
      title: "追加",
});

ドキュメントのIDを自動か指定するかでコードが変わります。
ボタンクリックで追加のコードを書いてみましたが、ラグがなくていい感じでした。

CRUDのU(更新)

updateDoc(doc(db, "posts", id), {
      text: "更新しました",
      title: "更新",
});

CRUDのD(削除)

deleteDoc(doc(db, "posts", id));

軽くフロントで触れるようにしてみた


コード

export default function Home() {
  type posts = { id: string; title: string; text: string };
  const [posts, setPosts] = useState([] as posts[]);
  const [title, setTitle] = useState("");
  const [text, setText] = useState("");

  useEffect(() => {
    const postData = collection(db, "posts");
    getDocs(postData).then((snapshot) => {
      setPosts(snapshot.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
    });
    onSnapshot(postData, (post) => {
      setPosts(post.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
    });
  }, []);

  const setDocument = (title: string, text: string) => {
    addDoc(collection(db, "posts"), {
      text: text,
      title: title,
    });
    setText("");
    setTitle("");
  };
  const upadteDocument = (id: string) => {
    updateDoc(doc(db, "posts", id), {
      text: "更新しました",
      title: "更新",
    });
  };
  const deleteDocument = (id: string) => {
    deleteDoc(doc(db, "posts", id));
  };
  return (
    <div className="App">
      <div>
        {posts.map((post, index) => (
          <div className="flex" key={index}>
            <h1 className="w-40">{post.title}</h1>
            <p className="w-72">{post.text}</p>
            <button onClick={() => upadteDocument(post.id)}>更新</button>
            <button onClick={() => deleteDocument(post.id)}>削除</button>
          </div>
        ))}
        <input
          className="border"
          type="text"
          onChange={(e) => setTitle(e.target.value)}
        />
        <input
          className="border"
          type="text"
          onChange={(e) => setText(e.target.value)}
        />
        <p></p>
        <button
          disabled={text == "" || title == ""}
          onClick={() => setDocument(title, text)}
        >
          データを追加
        </button>
      </div>
    </div>
  );
}

リアルタイム更新がかなり早くて良い感じでした。
セットアップも簡単だったので、小規模開発やMVPなどで使っていきたいです。

NCDCエンジニアブログ

Discussion