😆

React + TypeScript + Firebase

2023/06/16に公開

ChatGPT3.5に作り方教えてもらった!

ChatGPT3.5は古いコードしか書けないけど、Reactはそれほど破壊的変更がNext.jsほどないので、試しにモダンな技術構成で、作り方を教えてもらった。

やること

  1. TypeScriptに対応したプロジェクトを作る
  2. npmでfirebaseのパッケージをインストールする
  3. APIキーを設定する

プロジェクトを作成(TypeScriptを使用)

npx create-react-app --template typescript myapp

firebaseのパッケージを追加する(Firebase V9を使用)

npm install firebase

firebase.tsを作成する。ここに、FirebaseのAPIキーを貼り付ける

firebase.ts
// firebase.ts

import { initializeApp } from 'firebase/app';
import { getFirestore, collection, addDoc, getDocs } from 'firebase/firestore';

const firebaseConfig = {
  // あなたのFirebaseの設定情報(APIキーなど)を入力してください
  // 詳細な情報はFirebaseコンソールのプロジェクト設定から取得できます
  apiKey: "*************************",
  authDomain: "*************************",
  projectId: "*************************",
  storageBucket: "*************************",
  messagingSenderId: "*************************",
  appId: "*************************",
};

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

export { app, db, collection, addDoc, getDocs };

レイアウト用のCSSをApp.cssに記述する

App.css
/* App.css */

.container {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
}

h1 {
  text-align: center;
}

.form {
  margin-bottom: 20px;
}

.form-group {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.form-group label {
  flex-basis: 100px;
  margin-right: 10px;
}

input[type='text'],
input[type='number'] {
  flex-grow: 1;
  padding: 5px;
}

button {
  display: block;
  margin: 0 auto;
  padding: 10px 20px;
  background-color: #4285f4;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

ul.user-list {
  list-style-type: none;
  padding: 0;
}

.user-item {
  margin-bottom: 10px;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.user-name {
  font-weight: bold;
}

.user-age {
  color: #888;
}

追加と表示のUIとロジックを作る

App.tsxのファイルに、Firestoreにデータの追加とUIにFirestoreから、取得したデータを表示をする処理を追加します。

App.tsx
// App.tsx

import React, { useState, useEffect } from 'react';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { app, db, collection, addDoc, getDocs } from './firebase';
import './App.css'; // CSSファイルのインポート

// User型の定義
type User = {
  name: string;
  age: number;
};

const App: React.FC = () => {
  const [users, setUsers] = useState<User[]>([]);// useStateの初期値は空の配列
  const [name, setName] = useState('');// useStateの初期値は空文字
  const [age, setAge] = useState<number>(0);// useStateの初期値は0

  // useEffectの第2引数に空の配列を渡すことで、初回レンダリング時のみ実行される
  useEffect(() => {
    fetchUsers();
  }, []);

  // ユーザー一覧を取得する関数
  const fetchUsers = async () => {
    try {
      // usersコレクションの参照を取得
      const usersCollectionRef = collection(db, 'users');
      // usersコレクションの全てのドキュメントを取得
      const querySnapshot = await getDocs(usersCollectionRef);
      // ドキュメントのデータを配列に格納
      const userData: User[] = [];
      // ドキュメントのデータを配列に格納
      querySnapshot.forEach((doc) => {
        userData.push(doc.data() as User);
      });
      // ユーザー一覧を更新
      setUsers(userData);
    } catch (error) {
      console.error('Error fetching users:', error);
    }
  };
  // ユーザーを追加する関数
  const addUser = async () => {
    try {
      // usersコレクションの参照を取得
      const usersCollectionRef = collection(db, 'users');
      // ユーザーを追加
      await addDoc(usersCollectionRef, { name, age: Number(age) });
      console.log('User added successfully!');
      // ユーザー一覧を更新
      fetchUsers();
      // 入力欄をクリア
      setName('');
      // 入力欄をクリア
      setAge(0);
    } catch (error) {
      console.error('Error adding user:', error);
    }
  };

  return (
    <div className="container">
      <h1>Users</h1>
      <form
        className="form"
        onSubmit={(e) => {
          e.preventDefault();
          addUser();
        }}
      >
        <div className="form-group">
          <label htmlFor="name">Name:</label>
          <input
            id="name"
            type="text"
            placeholder="Enter name"
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
        </div>
        <div className="form-group">
          <label htmlFor="age">Age:</label>
          <input
            id="age"
            type="number"
            placeholder="Enter age"
            value={age.toString()}
            onChange={(e) => setAge(Number(e.target.value))}
          />
        </div>
        <button type="submit">Add User</button>
      </form>
      <ul className="user-list">
        {users.map((user, index) => (
          <li key={index} className="user-item">
            <div className="user-name">Name: {user.name}</div>
            <div className="user-age">Age: {user.age}</div>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default App;

動作の確認をする

コマンドを入力して、アプリを起動するとFirebaseが使えていることが確認できました。無料のChatGPT3.5でもちょっと昔の技術であれば、モダンな技術構成で作り方を教えてくれます。JavaScriptのFirebaseのドキュメントは、分かりにくくて以前は苦労しましたが、AIの力を借りると簡単にキャッチアップできました🙌

まとめ

ChatGPTに教えてもらいましたが、やはり公式ドキュメントを何度か読んだ方がいいですね。
ReactとVue.jsだと使い方は、違いますが一度動くものを見たら設定の仕方はわかるはずなので、何度も目を通して、理解を深めましょう。

https://firebase.google.com/docs/web/setup?hl=ja
https://firebase.google.com/docs/firestore/quickstart?hl=ja

Discussion