Lesson 9

Next.jsとFirebaseでTODOアプリの開発 - プロジェクトのセットアップ

Lesson 9 Chapter 1
作成するアプリについて

ハンズオンで作成するアプリケーション

本レッスンから実際にハンズオンでTODOアプリケーションを作成していきます。 今まで学んできたことを活かしてスキルを身につけていきましょう。

アプリケーション概要

完成形

実際に作成するアプリケーションの完成画面はこちらです。
nextjs-9-1

今回作成していくアプリについて

今回作成していくアプリについて仕組みを3層アーキテクチャの考え方を用いて簡単に説明していきます。

3層アーキテクチャとは

3層アーキテクチャとは、ソフトウェアアプリケーションを構成するための一般的な設計パターンの1つで、以下の3つのレイヤー(層)から構成されます。
プレゼンテーション層:ユーザーと直接やりとりするためのUI(ユーザーインターフェイス)を提供します。
アプリケーション層:この層は、ユーザーからのリクエストを受け取り、データの処理、DBへのアクセス等を提供します。
データベース層:アプリケーションで使用するデータの管理等を担当します。
このように、3層アーキテクチャは、アプリケーションの機能をそれぞれの役割に分けて設計することで、柔軟性や保守性を高めることができます。 また、各層は独立しているため、変更や拡張が容易になります。

下記が今回作成するTODOアプリケーションの3層アーキテクチャ設計を図で表したものになります。

nextjs-9-2 TODOアプリケーションを3層アーキテクチャ構造で表した図

プレゼンテーション層とアプリケーション層は今まで勉強してきたNext.jsが担当します。
プレゼンテーション層ではログインボタン・ログアウトボタンの表示、TODOの登録ボタンやTODOデータの一覧表示を担います。
アプリケーション層では各種ボタンを押下した時の処理や、データベースからTODOデータを取得する処理などクライアント側から 見えない部分の処理を行います。
データベース層のデータを保存するDBは今回はFirebaseというクラウドサービスの一部でDB機能を提供するCloud Firestoreを使用して作成していきます。 Cloud Firestoreについては次のチャプターで詳しく説明します。

機能

TODOアプリケーションの機能として以下の機能を実装していきます。

  • 認証機能:Firebase Auth認証処理を使用してユーザ認証を行う機能
  • TODO一覧表示:TODOを後程紹介するCloud Firestoreから取得し、表示する機能。
  • TODO追加:Cloud FirestoreにTODOデータを追加する機能。
  • TODO編集:Cloud Firestoreに入っているTODOデータを編集・更新する機能。
  • TODO削除:Cloud Firestoreに入っているTODOデータを削除する機能。
  • 追加・編集・削除機能を実行した後に一覧表示を行うことで現在のTODOを表示させる仕組みになります。

    それでは次のチャプターから各種アプリケーションのセットアップ・設定を行なっていきましょう。

    Lesson 9 Chapter 2
    Firebaseの設定

    Firebaseとは

    nextjs-9-3 本チャプターでセットアップしていく部分

    本チャプターではFirebaseの概要からTODOアプリで使用する機能のセットアップを行なっていきます。 Firebaseとは、簡単に解説するとGoogleが提供しているアプリの構築に役立つ機能の集まりになります。 全ての機能がGoogleのインフラ技術に支えられており、大規模なアプリケーションも構築することができます。 本アプリではその中でも認証機能を提供しているFirebase Authenticationと データベース機能を提供しているCloud Firestoreというサービスを使用していきます。

    プロジェクトの作成

    それでは実際にFirebaseのプロジェクトを作成していきましょう。
    Firebaseサービスの利用には事前にGoogleアカウントのログインが必要になりますので
    アカウントをお持ちでない方は作成後ログインをお願いします。
    nextjs-9-4 Firebase にアクセスし、「プロジェクトを作成」をクリックしましょう。 nextjs-9-5 プロジェクトの名前を決めていきます。プロジェクトの名前は任意でよろしいですが、当レッスンでは「Next-Firebase-TODO」として進めていきます。 プロジェクトの名前を決めたら利用規約等にチェックして続行をクリックしましょう。
    次のステップのGoogleアナリティクスを使用したレポート機能は当アプリでは使用しませんのでオフにして続行します。 続行をクリックするとプロジェクトの作成が始まります。
    nextjs-9-6 しばらくして上記の様な画像が表示されるとプロジェクトの作成は完了です。

    認証機能の有効化

    それでは次にアプリケーションログインする際の認証機能をFirebaseのAuthenticationを使用して有効化していきましょう。

    nextjs-9-7

    プロジェクトTOP画面の左側にあるメニューバーの構築というプルダウンをクリックして開きAuthenticationを選択してください。 Authentication設定画面に遷移したらSigh in methodタブをクリックし使用する認証機能を有効化していきます。
    現在使用できる認証機能は下記の様になります。 nextjs-9-8 本レッスンではGoogleログインを使用しますので追加のプロバイダからGoogleをクリックして有効にするトグルを押して有効化していきましょう。 有効化できたら下部の保存をクリックして保存します。
    ログインプロバイダの欄にGoogleプロバイダが追加されてステータスが有効となっていればGoogle認証機能の設定は完了です。 nextjs-9-9

    Cloud Firestoreの設定

    データベースの作成

    次にTODOタスクを管理するテーブルを格納するデータベースをCloud Firestoreを使用して作成していきます。 Authenticationを選択した時と同様にメニューバーの構築というプルダウンをクリックして開きFirestore Fatabaseを選択してください。 Cloud Firestoreのトップ画面に遷移したらデータベースの作成をクリックし、作成画面を開きましょう。 nextjs-9-10 ステップ①のCloud Firestoreのセキュリティ保護ルールの設定では本番環境モードを選択して、次へをクリックします。 ここで認証機能を実装しないアプリであればテストモードで次へ進めてください。
    次にロケーションの設定ですが、こちらはDBのサーバの場所を決めることができます。 nextjs-9-11 デフォルトではnam5(United States)でアメリカとなっていますので、プルダウンを選択し、asia-northeast1(Tokyo)を選択します。 選択できたら有効にするをクリックしてください。 nextjs-9-12
    有効化できたらデータベースが作成され、管理画面が表示されます。
    上記では「next-firebase-todo-fbac9」がデータベース名になります。

    テーブルの作成

    それではデータベースの中にTODOアプリのタスクを管理する「todos」コレクションを作成していきます。 nextjs-9-13 Cloud FirestoreではコレクションがRDBのテーブルに該当します。
    データベース管理画面でコレクション追加を選択してコレクションを作成していきます。
    コレクションIDはRDBでのテーブル名になりますので「todos」を入力し次へをクリックしてください。

    最初のレコードの作成

    コレクションIDの設定ができたら最初に挿入するドキュメントを設定します。
    ドキュメントはRDBのレコードに該当します。 ですので1つのドキュメントは1つのタスクということになります。 nextjs-9-14 ドキュメントIDの欄には自動生成を選択して一意の値を入れておきましょう。
    このドキュメントIDの値を用いてタスクに対して、編集や削除をしていきます。
    次にタスクの内容を保持する為のフィールドを
    「フィールド名:todo タイプ:string 値:テスト」として保存ボタンをクリックして保存します。
    nextjs-9-15 データベース管理画面でドキュメントが追加されたことを確認できたら最後に読み込みと書き込みの権限を設定していきます。

    コレクションの権限の変更

    データベース管理画面でルールタブをクリックします。 初期状態は下記の様になっています。

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /{document=**} {
          allow read, write: if false;
        }
      }
    }

    初期状態ではallow read, write: if false;の行でread(読み込み),write(書き込み)がfalse(不可)
    になっているので下記の様に修正します。

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /{document=**} {
          allow read: if true;
          allow write: if false;
        }
      }
    }

    これで読み込み可、書き込み不可の状態になりました。最後に公開をクリックして適用完了です。 これでTODOアプリケーションのCloud FIrebaseの設定は完了です。
    FirebaseはCloud Firestore以外にも色々な機能がありますので是非調べてみてください。
    次のチャプターではNext.js側のプロジェクトのセットアップとCloud Firebaseと連携して最初のドキュメントの内容の表示確認を行なっていきます。

    Lesson 9 Chapter 3
    Next.jsのセットアップ

    Nextプロジェクトの作成

    nextjs-9-16 本チャプターで進めていく部分

    前チャプターではFirebaseのセットアップをしていきました。本チャプターではNext.jsのセットアップを行っていきます。
    それでは早速TODOアプリ用のNext.jsプロジェクトを作成していきましょう。 npx create-next-app next-firebase-todo-app
    ※本アプリではTypescriptとESLintをオフにしてプロジェクトを作成していきます。

    プロジェクトにFirebaseSDKのインストール

    作成したNext.jsアプリでFirebaseと連携する為にFirebaseSDKをプロジェクトにnpmインストールしていきます。 FirebaseSDKとはFirebaseサービスの操作をプログラム中に記述できる様にしたツールになります。 FirebaseSDKのインストールは下記のコマンドで行えます。
    npm install firebase

    Next.jsとFirebaseの連携

    apikeyの取得

    次にプロジェクトを正しく自分のCloud Firebaseに接続する為にFirebaseプロジェクトにアプリを追加しapikey等を取得していきます。 nextjs-9-17 まずはFirebaseのプロジェクトのTOP画面に行き、</>のマークのボタンを押しアプリ追加画面を開きます。
    任意のアプリ名を入力し、アプリを登録をクリックするとCloud Firebaseと接続する為のapikey等が発行されます。 nextjs-9-18 ここにはapiKeyやprojectIdなどが表示されていますので、これをNext.jsプロジェクト側で割り当ててFirebaseと連携するようにしていきます。
    またapiKeyなどは第三者に見られると悪用される可能性がありますので、envファイルに設定し他人に見られない様にしていきます。
    ルートディレクトリに.env.localファイルを作成し、下記の様にコピーして記入していきます。

    .env.local
    NEXT_PUBLIC_FIREBASE_APIKEY = Firebaseで発行したapikey
    NEXT_PUBLIC_FIREBASE_DOMAIN = Firebaseで発行したauthDomain
    NEXT_PUBLIC_FIREBASE_FIREBASE_PROJECT_ID = Firebaseで発行したprojectId
    NEXT_PUBLIC_FIREBASE_FIREBASE_STORAGE_BUCKET = Firebaseで発行したstorageBucket
    NEXT_PUBLIC_FIREBASE_FIREBASE_FIREBASE_SENDER_ID = Firebaseで発行したmessagingSenderId
    NEXT_PUBLIC_FIREBASE_FIREBASE_APP_ID = Firebaseで発行したappId

    FirebaseSDKの初期化

    正しく自分のCloud Firebaseに接続するにはFirebaseSDKを取得したapikeyを使用して初期化する必要があります。 SDK初期化用ファイルのfirebase.jsをルートディレクトリに作成し、下記の様に実装します。

    firebase.js
    import { getFirestore } from "firebase/firestore";
    import { getApps, initializeApp } from "firebase/app";
    
    const firebaseConfig = {
        apiKey: process.env.NEXT_PUBLIC_FIREBASE_APIKEY,
        authDomain: process.env.NEXT_PUBLIC_FIREBASE_DOMAIN,
        projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
        storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
        messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_SENDER_ID,
        appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
    };
    
    if (!getApps()?.length) {
        initializeApp(firebaseConfig);
    }
    
    export const db = getFirestore();

    上記のfirebaseConfigという変数でapiキー等をセットしてinitializeApp関数でSDKを初期化させています。 Cloud Firestoreを使用したい際は最下行でexportしているdbを使用したいファイルでインポートすれば使用できます。

    Cloud Firestoreとの連携確認

    それではCloud Firestoreと連携してtodosコレクションの値を取得してみましょう。 pages/index.jsxの中身を全て削除して下記のコードを記載します。

    index.jsx
    import { useState, useEffect } from "react";
    import { db } from "../firebase.js";
    import { collection, getDocs } from 'firebase/firestore';
    
    const Index = () => {
        const [todos, setTodos] = useState([{ id: "", todo: "" }]);
    
        // Firestoreのデータを取得;
        useEffect(() => {
            const firebase = async () => {
                try {
                    const col = collection(db, "todos");
                    const querySnapshot = await getDocs(col);
                    setTodos(
                        querySnapshot.docs.map((doc) => ({
                            id: doc.id,
                            todo: doc.data().todo,
                        }))
                    );
                } catch (error) {
                    console.log(error);
                }
            };
            firebase();
        }, []);
    
        return (
            
                <h2>Firebase連携確認</h2>
                <ul>
                    {todos.map((todo) => {
                        return <li key={todo.id}>{todo.todo}</li>;
                    })}
                </ul>
            >
        );
    };
    
    export default Index;
    nextjs-9-19

    nom run devで開発用サーバを起動し、http://localhost:3000/にアクセスして todosコレクションに登録した最初のドキュメントのtodoの内容が表示されればCloud Firestoreとの連携は完了です。
    次のレッスンではTODOアプリケーションの画面の作成と各種機能の実装を行なっていきます。