ChatGPTを使用したアプリ開発記【投げ銭（ギフティング）機能を実装】

## 🔧Firestore Databaseの設定
データタブ
![スクリーンショット 2025-05-09 9.16.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058366/012f667e-9881-48fd-8bf4-b2d7430a9c54.png)
ルールタブ
```json
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;  // ← 誰でも読み書き可（開発中のみ）
    }
  }
}
```

## ✅ 1. Firestoreの初期化
```firebase.js
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';

const firebaseConfig = {
  apiKey: "your_api_key",
  authDomain: "your_project_id.firebaseapp.com",
  projectId: "your_project_id",
  // その他設定
};

const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
```
## ✅ 2. ギフト送信用の関数
```GiftButton.js
import { useState } from "react";
import { db } from './firebase';

// Firestore の関数をインポートしています：
// collection：コレクション参照を作る
// addDoc：新しいドキュメントを追加する
// serverTimestamp：サーバー側の現在時刻をタイムスタンプとして使用する
import { collection, addDoc, serverTimestamp } from "firebase/firestore";

// 認証情報（ログインユーザー）を取得するカスタムフック useAuth をインポート。
// おそらくこのフックは、現在ログインしているユーザーを返します。
import { useAuth } from './useAuth';

// Firestore の 'gifts' コレクションに新しいギフト情報を追加する処理を開始。
function GiftButton({ toUser }) {
  const [amount, setAmount] = useState(100);
  const [message, setMessage] = useState('');
  const user = useAuth();

  const handleSendGift = async () => {
    if (!user) return;

    await addDoc(collection(db, 'gifts'), {
      fromUser: user.email,
      toUser,
      amount,
      message,
      createdAt: serverTimestamp()
    });

    alert('🎁 ギフトを送信しました！');
    // 送信後にメッセージ入力欄をリセット。
    setMessage('');
  };

  return (
    <div>
      <input
        type="number"
        value={amount}
        min="50"
        onChange={(e) => setAmount(Number(e.target.value))}
        placeholder="金額"
      />
      <input
        type="text"
        value={message}
        onChange={(e) => setMessage(e.target.value)}
        placeholder="メッセージ(任意)"
      />
      <button onClick={handleSendGift}>投げ銭🎁</button>
    </div>
  );
}

export default GiftButton;
```
## ✅ 3. プロフィールページでの表示
```Profile.js
// Firestore 関連の関数をまとめてインポート：
// collection：コレクション参照
// query, where：条件付きでクエリを作成
// getDocs：データを取得
// addDoc：ドキュメントを追加（ギフト送信用）
// Timestamp：作成時刻の記録に使う
import { collection, query, where, getDocs } from 'firebase/firestore';

import { db } from './firebase';

// React のフック：
// useState: 状態管理（例: ギフトの一覧）
// useEffect: 初回レンダリング時の処理（データ取得）
// useContext: コンテキストから投稿データを取得
import { useEffect, useState, useContext } from 'react';

function GiftList({ userId }) {
  const [gifts, setGifts] = useState([]);

// React の 副作用フック（useEffect）の開始です。
// この関数の中で、初期表示時や依存値が変わったときに非同期データ取得処理などを行います。
  useEffect(() => {

// fetchGifts という非同期関数を定義しています。
// この関数の中で Firestore からギフト情報を取得します。  
    const fetchGifts = async () => {

// Firestore 内の 'gifts' コレクション（ギフト一覧）を参照。
// userId（つまりこのプロフィールページのユーザー）と一致するギフトだけを絞り込む。
// query(...) により、コレクション＋条件が合わさったクエリオブジェクトを作成。
      const q = query(collection(db, 'gifts'), where('toUser', '==', userId));

// 上で作ったクエリ q に従って Firestore から該当ドキュメントの一覧を取得。
      const snapshot = await getDocs(q);

// 取得した各ドキュメント（doc）から .data() を呼び出して純粋なデータオブジェクトに変換
// map(...) によってそれを配列にし、setGifts() で React の状態にセットします。
// これによりギフトの一覧が画面に表示されるようになります。
      setGifts(snapshot.docs.map(doc => doc.data()));
    };

// 上で定義した fetchGifts() を実行します。
// これによりページの初期描画時にギフト一覧が取得されます。
    fetchGifts();

// userId が変わったとき（別のユーザーのプロフィールページを表示したとき）にも fetchGifts() を再実行します。
  }, [userId]);

  return (
    <div>
      <h4>🎁 受け取ったギフト</h4>
      <ul>
        {gifts.map((gift, i) => (
          <li key={i}>
            {gift.fromUser} さんから {gift.amount} コイン「{gift.message}」
          </li>
        ))}
      </ul>
    </div>
  );
}
```
## 🔧 Profile の return 内で表示させる：
```Profile.js
<GiftForm toUser={userId} />
<GiftList userId={userId} />
```
## UI

![スクリーンショット 2025-05-09 11.04.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058366/3593d0ab-e64d-4d8c-a9e0-103bd2a644b0.png)