【ポートフォリオ作成】Udemyの動画で家計簿アプリを作成中です。

2024年7月23日

Reactの初歩を学んだところで、次のステップの教材を探していたところUdemyで良さそうな動画を見つけました。
完成率は60~70%の段階といったところですが、下記に自身のポートフォリオとして掲載します。
https://my-tech-blog-five.vercel.app/portfolio


■Udemy動画

講師:ポテナスさん
【『React』×『TypeScrip』入門 】家計簿アプリ作成でReactとTypeScriptの開発方法を学ぼう

https://www.udemy.com/course/reacttypescrip-reacttypescript/

主に以下が学べます。(※先ほども書きましたが進捗率60~70%なので、まだ追加されると思います)

  • React全般(Hooks、コンポーネント)
  • TypeScript
  • Firebase(Firestore)
  • MUI
  • React-hook-forms
  • My Calendar
  • react-chartjs-2

ちまたでは初心者向けの「To doアプリ作成」とかの動画とかよく見かけますが、
基礎的なところはしまぶーさんのYoutube動画やブログ作成などでも結構触りましたし、
何よりTo doアプリを作ってもおそらく使わないので、作ってても面白くない・・・。

(しまぶーさんのYoutube動画のリンクはこちらの記事を参考にしてください。)

https://my-tech-blog-five.vercel.app/blogs/2mtxgg6mey3


こちらの教材であればたくさんのReactライブラリ(+TypeScriptも)やデータベースに関わるバックエンド(Firebase)まで触れますし、
一番気に入ったのは実用的なアプリが作れるところです。
完成後は自身でも欲しい機能を追加しながら、実際に家計管理に使おうと思っています。

ちなみにUdemyは定期的にセールをやっていますので、購入する場合は活用する方が絶対おススメです。

ユーザー登録&ログイン機能を実装する

動画内では紹介されていませんが、後々個人利用もしたいと考えているので
ユーザー登録&ログイン機能を自身で調べながら追加したので概要を記載しておきます。


Firebaseを使用している場合は下記が最低限必要となります。
(apikeyの設定など、今回紹介した動画内で説明されている基本的なFirebaseの設定は完了しているものとします)

  1. ユーザー登録&ログイン画面の実装
  2. Firestoreセキュリティルールの追加
  3. Firestoreに登録するデータ構造の変更

私と同じく初心者だとそもそも何をすればよいかがまず分からないと思いますが、
「外部からきたユーザーが、その人に紐づけられたFirestoreデータベースの編集ができるようにする」ことが必要となります。

  1. ユーザー登録&ログイン画面の実装

    →外部からきたユーザーがUIDをFirestoreに追加できるようにする

  2. Firestoreセキュリティルールの追加
    →UID(ユーザーごとのID)が存在する場合、Firestoreにアクセスしてもいいよ。と条件を追加する

  3. Firestoreに登録するデータ構造の変更

    →登録するデータベース情報(日付ごとの収支データ)にUIDを組み込む

1.ユーザー登録&ログイン画面の実装

下記のサイトを参考にユーザー登録とログイン画面を作成しました。

https://qiita.com/takahashi-yoji/items/a2a97b90a5b5e7cfc224

https://qiita.com/takahashi-yoji/items/055b44dda64fb6f33ad0

アプリにアクセスした場合の最初の表示を「ユーザー登録とログイン画面」にする

登録、またはログインが完了したら家計簿アプリにユーザーを移動させてあげる
といった処理が必要となります。

先に下記にファイルルーティングを載せておきます(Next.js ver.14 / appルーター形式)
不明点を検索して解説記事とか見てもこのコードってどのファイルに書いたらいいの?って
ファイルルーティングを知りたいことも多いと思いますが、

意外と載ってないことが多いですね。

/project-root
├── src
│   ├── app
│   │   ├── page.tsx
│   │   ├── components
│   │   ├── Home/Home.tsx
│   │   ├── Singup/Signup.tsx
│   │   └── ... (他のファイルやディレクトリ)
│   ├── firebase.ts
│   └── ... (他のファイルやディレクトリ)
├── public
│   └── ... (publicディレクトリ内のファイルやディレクトリ)
├── next.config.mjs
├── package.json
└── ... (他のファイルやディレクトリ)
<Signup.tsx>

const signup = async () => {
    await createUserWithEmailAndPassword(auth, email, password)
    .then((useCredential) => {
      console.log(useCredential);

      // ユーザー専用のコレクションを作成
      setDoc(doc(db, 'users', useCredential.user.uid), {
        email: useCredential.user.email,
        createdAt: new Date(),
      });

      navigate('/applayout');
    })
    .catch((error) => {
      alert(error.message);
      console.error(error);
    });
  };

setDocの部分でFirebase内にユーザーIDが登録されます。
また、naviigate('/applayout');の部分でアプリのトップページに遷移させるようになっています。

2.Firestoreセキュリティルールの追加

Firebaseにログインし、自身のプロジェクト画面から「Firestore Database」→「ルール」タブを選択します。

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {

    // This rule allows anyone with your Firestore database reference to view, edit,
    // and delete all data in your Firestore database. It is useful for getting
    // started, but it is configured to expire after 30 days because it
    // leaves your app open to attackers. At that time, all client
    // requests to your Firestore database will be denied.
    //
    // Make sure to write security rules for your app before that time, or else
    // all client requests to your Firestore database will be denied until you Update
    // your rules
    match /{document=**} {
      allow read, write: if request.time < timestamp.date(2024, 8, 9);
      allow read, write: if request.auth != null && request.auth.uid == resource.data.userId;
    }
  }
}

今回は

allow read, write: if request.auth != null && request.auth.uid == resource.data.userId;

の部分のみを追加しました。
if以降の部分は「request.auth != null 」と「 request.auth.uid == resource.data.userId」の部分に分けられます。
(&&は論理和演算子なので、両方が成立する場合readとwriteを許可する)
「request.auth != null 」→リクエストが認証されたユーザーからのものであることを確認します。
Firebase Authenticationを使用してユーザーが認証されている場合、request.authが存在するためこの条件は真となります。
「 request.auth.uid == resource.data.userId」→この条件は、リクエストを行ったユーザーのUID(request.auth.uid)が、
ドキュメントの userId フィールドに保存されているUID(resource.data.userId)と一致することを確認します。
これにより、ユーザーは自分自身のデータにのみアクセスできるようになります。

3.Firestoreに登録するデータ構造の変更

講座内では
・Transaction→日付ごとの収支データ
となっていたのですが、これを

・ユーザーID→Transaction→日付ごとの収支データ
となるようにコードを変更します。

例として存在するデータの取得(getDocs)部分のコードであれば次のようになります。

<page.tsx>

const [transactions, setTransactions] = useState<Transaction[]>([]);
  const [currentMonth, setCurrentMonth] = useState(new Date());
  const auth = getAuth();
  const user = auth.currentUser;
  console.log(user);

//firestoreのデータを【ユーザーのUIDと一致するもののみ】を全て取得
  useEffect(() => {
    if (user) {
      const fetchTransactions = async () => {
        try {
          const userTransactionsCollection = collection(db, 'users', user.uid, 'Transactions');
          const querySnapshot = await getDocs(userTransactionsCollection);
          console.log(querySnapshot);

          const transactionsData =querySnapshot.docs.map((doc) => {
            // doc.data() is never undefined for query doc snapshots
            // console.log(doc.id, " => ", doc.data());
            return {
              ...doc.data(),
              id: doc.id,
            } as Transaction;
          });
          console.log(transactionsData);
          setTransactions(transactionsData);
        } catch(err) {
          if(isFireStoreError(err)) {
            console.error('firestoreのエラーは:', err);
          } else {
            console.error('一般的なエラーは:', err);
          }
          //error
        }
      }
      fetchTransactions();
    }
  
  }, [user])

変更したのは

const auth = getAuth();  
const user = auth.currentUser; 

の部分と、

useEffectの次のif(user)(userが存在する=trueの場合に処理を実行する)

あとは、

const userTransactionsCollection = collection(db, 'users', user.uid, 'Transactions');

このうち、「'users', user.uid,」の部分のみを追記して、Transactionの上位にユーザーIDが来るように設定しました。

まとめ

記事内にも書きましたが、初心者であればそもそも何をすればよいかがまず分からない、ので
どういう仕組みであればやりたいことが実現できるのか、全体のイメージを掴むことが難しかったです。
まだ解説しきれていない部分もありますが、そもそもアプリ作成の講座がまだ完了できていませんので・・・(24年7月28日時点)
この記事についてもまた更新していきたいと思います。


記事一覧に戻る