Next.js アプリを使用して Firebase App Hosting にデプロイする

1. 始める前に

この Codelab では、レストランのレビュー サイトである Friendly Eats という Next.js ウェブアプリを使用して、Firebase App Hosting にデプロイする方法について学びます。

Friendly Eats ウェブアプリ

完成したウェブアプリには、Firebase を使用して Next.js アプリを構築する方法を示す便利な機能が用意されています。

  • 自動ビルドとデプロイ: この Codelab では、Firebase App Hosting を使用して、構成済みのブランチに push するたびに Next.js コードを自動的にビルドしてデプロイする方法について説明します。
  • ログインとログアウト: 完成したウェブアプリでは、ユーザーが Google を使用してログイン/ログアウトできます。ユーザーのログインと永続性は、すべて Firebase Authentication を通じて管理されます。
  • 画像: 完成したウェブアプリでは、ログインしたユーザーがレストランの画像をアップロードできます。画像アセットは Cloud Storage for Firebase に保存されます。Firebase JavaScript SDK は、アップロードされた画像への公開 URL を提供します。この公開 URL は、Cloud Firestore の関連するレストラン ドキュメントに保存されます。
  • フィルタ: 完成したウェブアプリでは、ログインしたユーザーがカテゴリ、場所、価格に基づいてレストランのリストをフィルタできます。使用する並べ替え方法をカスタマイズすることもできます。データは Cloud Firestore からアクセスされ、使用されたフィルタに基づいて Firestore クエリが適用されます。
  • レビュー: 完成したウェブアプリでは、ログインしたユーザーが星評価とテキスト メッセージで構成されるレストランのレビューを投稿できます。レビュー情報は Cloud Firestore に保存されます。
  • レビューの要約: 完成したウェブアプリは、Gemini モデルを使用してレビューを自動的に要約します。AI によって生成された要約は Cloud Firestore に保存されます。

前提条件

  • Next.js と JavaScript の知識

学習内容

  • Next.js App Router とサーバーサイド レンダリングで Firebase を使用する方法
  • サーバーサイド専用のシークレットを使用して Gemini API への呼び出しを承認する方法

必要なもの

  • お好みのブラウザ(Google Chrome など)
  • IDX.dev(ウェブベースのワークスペース)へのアクセス
  • Firebase プロジェクトの作成と管理に使用する Google アカウント
  • GitHub アカウント(上記のメール アカウントと同じである必要はありません)

2. 開発環境と GitHub リポジトリを設定する

この Codelab では、アプリのスターター コードベースを提供し、Firebase CLI と IDX.dev を使用します。

新しい GitHub リポジトリを作成して IDX にインポートする

Firebase App Hosting では、GitHub リポジトリを設定して、構成されたブランチに push するたびに Next.js コードをビルドしてデプロイできます。

  1. この Codelab 用の新しい GitHub リポジトリ(https://github.com/new)を作成します。任意の名前(例: MyFriendlyEatsCodelab)を付けます。
  2. 新しいリポジトリの URL をコピーします。次のようになります。
    https://github.com/USER_NAME/REPOSITORY_NAME.git
  3. https://idx.google.com にアクセスしてログインします。
  4. [Import a repo] をクリックし、コピーした GitHub URL を貼り付けます。
    IDX から GitHub へのリンクを求めるメッセージが表示され、その後、(空の)リポジトリがクローンされます。

コードラボのソースコード リポジトリを表示する

Codelab のソースは https://github.com/firebase/friendlyeats-web で確認できます。friendlyeats-web リポジトリには複数のプラットフォーム用のサンプル プロジェクトが含まれています。

この Codelab では、Firebase App Hosting と Gemini API のみに焦点を当てています。これは、完全版の Codelab「Firebase を Next.js アプリと統合する」の短縮版です。この短縮版の Codelab では、friendlyeats-web リポジトリの #io-connect ブランチのソースコード(具体的には nextjs-step10 ディレクトリ)のみを操作する必要があります。

friendlyeats-web リポジトリの次の追加ディレクトリに注意してください。この Codelab ではこれらのディレクトリは必要ありませんが、どのようなものかを知っておくと便利です。

Codelab のソースを新しいリポジトリにコピーする

nextjs-step10 ディレクトリを独自のリポジトリにコピーする方法は次のとおりです。

  1. IDX で、[メニュー] > [ターミナル] > [新しいターミナル] を使用してターミナルを開きます。
  2. giget npm パッケージを使用して、io-connect ブランチから nextjs-step10 ディレクトリのみを取得します。
    npx giget@latest gh:firebase/friendlyeats-web/nextjs-step10#io-connect . --force
    
  3. git を使用してローカルで変更を追跡します。
    git add -A
    git commit -m "codelab starting point"
    git branch -M main
    git push -u origin main
    

GitHub リポジトリにスターター コードが表示されます。

3. スターター コードベースを確認する

このセクションでは、この Codelab で機能を追加するアプリのスターター コードベースのいくつかの領域を確認します。

フォルダとファイルの構造

次の表に、アプリのフォルダとファイル構造の概要を示します。

フォルダとファイル

説明

src/components

フィルタ、ヘッダー、レストランの詳細、レビュー用の React コンポーネント

src/lib

React や Next.js に必ずしもバインドされないユーティリティ関数

src/lib/firebase

Firebase 固有のコードと Firebase 構成

public

ウェブアプリの静的アセット(アイコンなど)

src/app

Next.js アプリルーターを使用したルーティング

src/app/restaurant

API ルート ハンドラ

package.jsonpackage-lock.json

npm を使用したプロジェクトの依存関係

next.config.js

Next.js 固有の構成(サーバー アクションが有効

jsconfig.json

JavaScript 言語サービスの構成

サーバー コンポーネントとクライアント コンポーネント

このアプリは、App Router を使用する Next.js ウェブアプリです。サーバー レンダリングはアプリ全体で使用されます。たとえば、src/app/page.js ファイルはメインページを担当するサーバー コンポーネントです。src/components/RestaurantListings.jsx ファイルは、ファイルの先頭にある "use client" ディレクティブで示されるクライアント コンポーネントです。

インポート ステートメント

一部のファイルには、次のような import ステートメントが含まれていることがあります。

import RatingPicker from "@/src/components/RatingPicker.jsx";

このアプリでは、@ 記号を使用して、相対インポート パスの煩雑さを回避しています。これは、パス エイリアスによって実現されています。

Firebase 固有の API

すべての Firebase API コードは src/lib/firebase ディレクトリにラップされています。個々の React コンポーネントは、Firebase 関数を直接インポートするのではなく、ラップされた関数を src/lib/firebase ディレクトリからインポートします。

モックデータ

レストランとレビューのモックデータは src/lib/randomData.js ファイルに含まれています。そのファイルからのデータは、src/lib/fakeRestaurants.js ファイルのコードで組み立てられます。

4. Firebase プロジェクトを設定する

このセクションでは、Firebase プロジェクトを設定し、Firebase ウェブアプリを関連付けます。また、サンプル ウェブアプリで使用される Firebase サービスも設定します。

Firebase プロジェクトを作成する

  1. 前の手順で使用したのと同じ Google アカウントを使用して、Firebase コンソールにログインします。
  2. ボタンをクリックして新しいプロジェクトを作成し、プロジェクト名(例: FriendlyEats Codelab)を入力します。
  3. [続行] をクリックします。
  4. Firebase の利用規約が表示されたら、内容を読み、同意して [続行] をクリックします。
  5. (省略可)Firebase コンソールで AI アシスタンス(「Gemini in Firebase」)を有効にします。
  6. この Codelab では Google アナリティクスは必要ないため、Google アナリティクスのオプションをオフに切り替えます
  7. [プロジェクトを作成] をクリックし、プロジェクトのプロビジョニングが完了するまで待ってから、[続行] をクリックします。

Firebase の料金プランをアップグレードする

Firebase App Hosting と Cloud Storage for Firebase を使用するには、Firebase プロジェクトが従量課金制(Blaze)のお支払いプランに登録されている必要があります。つまり、Cloud 請求先アカウントにリンクされている必要があります。

  • Cloud 請求先アカウントには、クレジット カードなどのお支払い方法が必要です。
  • Firebase と Google Cloud を初めて使用する場合は、$300 のクレジットと無料トライアル用 Cloud 請求先アカウントを利用できるかどうかご確認ください。
  • この Codelab をイベントの一環として実施する場合は、Cloud クレジットが利用可能かどうかを主催者にお問い合わせください。

プロジェクトを Blaze プランにアップグレードする手順は次のとおりです。

  1. Firebase コンソールで、[プランをアップグレード] を選択します。
  2. Blaze プランを選択します。画面の指示に沿って、Cloud 請求先アカウントをプロジェクトにリンクします。
    このアップグレードの一環として Cloud 請求先アカウントを作成する必要があった場合は、Firebase コンソールのアップグレード フローに戻ってアップグレードを完了する必要がある場合があります。

5. App Hosting バックエンドを作成する

このセクションでは、git リポジトリのブランチを監視するように App Hosting バックエンドを設定します。バックエンドが通信するすべてのサービスも構成します。

このセクションの最後では、GitHub のリポジトリに接続された App Hosting バックエンドが作成されます。このバックエンドは、新しい commit を main ブランチに push するたびに、アプリの新しいバージョンを自動的に再ビルドしてロールアウトします。

バックエンドの作成

  1. Firebase コンソールで、App Hosting ページに移動します。App Hosting コンソールのゼロ状態。[使ってみる] ボタンが表示されている
  2. [開始] をクリックして、バックエンド作成フローを開始します。
  3. プロンプトに沿って、先ほど作成した GitHub リポジトリをインポートして接続します。
  4. デプロイ設定を行います。
    • ルート ディレクトリを / のままにする
    • ライブブランチを main に設定する
    • 自動ロールアウトを有効にする
  5. バックエンドに friendlyeats-codelab という名前(または任意のバックエンド名)を付けます。これは、バックエンドへのアクセスに使用されるドメインの一部になります。
    このワークフローでは、Firebase プロジェクトに Firebase ウェブアプリも自動的に作成されます。この Codelab の後半では、このウェブアプリの構成値を使用して、コードベースを Firebase プロジェクトに接続します。
  6. [Finish and deploy] をクリックします。しばらくすると、新しいページに移動し、新しい App Hosting バックエンドのステータスを確認できます。
  7. App Hosting ダッシュボードで、新しいドメインをコピーします。
    BACKEND_ID--PROJECT_ID.REGION.hosted.app のようなパターンになります。このドメインは、後で Firebase Authentication を設定する際に必要になります。

DNS の伝播と SSL 証明書の作成により、ドメインが機能し始めるまでに数分かかることがあります。バックエンドの作成中に、Firebase プロジェクトの残りの部分の設定とバックエンドの構成(この Codelab の次のステップ)に進みます。

GitHub リポジトリの main ブランチに新しい commit を push するたびに、Firebase コンソールで新しいビルドとロールアウトが開始されます。ロールアウトが完了すると、サイトは自動的に更新されます。

6. 他の Firebase サービスを設定する

この Codelab では Firebase App Hosting と Gemini API のみに焦点を当てていますが、動作するウェブアプリには他の Firebase サービスが必要です。これらのサービスをアプリで動作させるためのコードは、独自の GitHub リポジトリにコピーしたコードベースの一部ですが、Firebase プロジェクトでこれらのサービスを設定する必要があります。

Authentication を設定する

  1. Firebase コンソールで [認証] に移動します。
  2. [開始] をクリックします。
  3. [追加のプロバイダ] 列で、[Google > 有効にする] をクリックします。
    1. [プロジェクトの公開名] テキスト ボックスに、My FriendlyEatsCodelab app などの名前を入力します。
    2. [プロジェクトのサポートメール] プルダウンからメールアドレスを選択します。
    3. [保存] をクリックします。
  4. [認証] ページの [設定] タブをクリックします。
    1. 画面の左側のメニューで [Authorized Domains] をクリックします。
    2. [ドメインを追加] をクリックし、新しく作成した App Hosting ドメイン(.hosted.app で終わるドメイン)を追加します。
    3. [追加] をクリックして保存します。

Cloud Firestore を設定する

  1. Firebase コンソールの左側のパネルで [ビルド] を展開し、[Firestore データベース] を選択します。
  2. [データベースを作成] をクリックします。
  3. [データベース ID] は (default) に設定したままにします。
  4. データベースのロケーションを選択し、[次へ] をクリックします。
    実際のアプリでは、ユーザーに近いロケーションを選択します。
  5. [テストモードで開始] をクリックします。セキュリティ ルールに関する免責条項を確認します。
    この Codelab の後半で、データを保護するためのセキュリティ ルールを追加します。データベースのセキュリティ ルールを追加せずに、アプリを配布または公開しないでください。
  6. [作成] をクリックします。

Cloud Storage for Firebase を設定する

  1. Firebase コンソールの左側のパネルで、[ビルド] を展開し、[ストレージ] を選択します。
  2. [開始] をクリックします。
  3. デフォルトの Storage バケットのロケーションを選択します。
    US-WEST1US-CENTRAL1US-EAST1 のバケットは、Google Cloud Storage の「無料枠」を利用できます。他のすべてのロケーションのバケットは、Google Cloud Storage の料金と使用量に従います。
  4. [テストモードで開始] をクリックします。セキュリティ ルールに関する免責条項を読みます。
    この Codelab の後半で、データを保護するためのセキュリティ ルールを追加します。Storage バケットのセキュリティ ルールを追加せずに、アプリを配布または公開しないでください。
  5. [作成] をクリックします。

7. ウェブアプリを構成する

Firebase プロジェクトを作成し、アプリで使用するすべての Firebase サービスを有効にしたので、IDX で作業を開始して、これらのサービスを使用するようにウェブアプリを構成できます。

IDX 内で Firebase CLI にログインする

IDX には Node.js と Firebase CLI がすでにインストールされているため、インストールをスキップして CLI の設定を開始できます。

  1. IDX 内のターミナルで次のコマンドを実行して、CLI が先ほど作成した Firebase プロジェクトを使用するように構成します。
    firebase login --no-localhost
    firebase use --add
    
    エイリアスの入力を求められたら、「codelab」と入力します。
  2. Firebase にデータを収集させるかどうかによって、Y または N を入力します。この Codelab ではどちらのオプションでも構いません。
  3. ブラウザで Google アカウントを選択し、[許可] をクリックします。

セキュリティ ルールとインデックスをデプロイする

GitHub リポジトリにコピーしたコードには、Firestore(firestore.rules 内)と Cloud Storage for Firebase(storage.rules 内)のセキュリティ ルールがすでに設定されています。セキュリティ ルールをデプロイすると、データベースとバケット内のデータが不正使用から保護されます。

CLI を使用して、Firestore(firestore.indexes.json)のインデックスのセットをデプロイし、高度なクエリを有効にすることもできます。

  1. IDX 内のターミナルで、次のコマンドを実行して、これらのセキュリティ ルールとインデックスをデプロイします。
    firebase deploy --only firestore,storage
    
  2. "Cloud Storage for Firebase needs an IAM Role to use cross-service rules. Grant the new role?"」というメッセージが表示されたら、Enter を押して [はい] を選択します。

Firebase 構成をウェブアプリのコードに追加する

  1. Firebase コンソールで次の操作を行います。
    1. プロジェクト設定に移動します。
    2. [アプリ] セクションまで下にスクロールし、App Hosting バックエンドと同じ名前のアプリを選択します。
    3. [SDK の設定と構成] で [Config] オプションを選択し、firebaseConfig 変数のプロパティとその値をコピーします。
  2. IDX で次の操作を行います。
    1. apphosting.yaml ファイルを開きます。ここでは、App Hosting で環境変数、シークレット、ランタイム構成を設定します。
    2. 指定された環境変数の値に、Firebase コンソールからコピーした構成値を入力します。例(実際の値に置き換えてください):
      runConfig:
          minInstances: 0
          maxInstances: 2
      env:
          # Get these values from the Firebase console
          - variable: NEXT_PUBLIC_FIREBASE_API_KEY
              value: xxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx
          - variable: NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN
              value: project-id.firebaseapp.com
          - variable: NEXT_PUBLIC_FIREBASE_PROJECT_ID
              value: project-id
          - variable: NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET
              value: project-id.firebasestorage.app
          - variable: NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID
              value: 111111111111
          - variable: NEXT_PUBLIC_FIREBASE_APP_ID
              value: 1:111111111111:web:aaaaaaaaaaaaaaaaaaaaaa
      
    3. ファイルを保存します。次に、IDX 内のターミナルで次のコマンドを実行して、変更を GitHub に push します。
      git commit -a -m "Setup Firebase Config"
      
      git push
      
  3. Firebase コンソールに戻り、アプリ ホスティング ページに戻って、次の操作を行います。
    1. バックエンドの [ダッシュボードを表示] をクリックします。
    2. git push から新しいビルドがトリガーされたことを確認します。ビルドと Cloud Run へのロールアウトが完了するまでに約 3 分かかります。進行状況は、build-ID チップをクリックして確認できます。
    3. コンソール ページを更新して、ロールアウトが完了したかどうかを確認します。完了したら、[domains] の下にあるドメインのリンク(.hosted.app で終わる)をクリックして開き、新しくデプロイされたアプリを表示します。

おめでとうございます。最初のウェブアプリをデプロイしました。もう少し詳しく見てみましょう。

8. ブラウザでウェブアプリを試す

Firebase Authentication でログインできることを確認する

  1. ブラウザで、ウェブアプリを表示しているページを更新します。
  2. [Sign in with Google] をクリックします。
  3. ログアウトしてもう一度ログインしてください。 ページは更新されずにリアルタイムで更新されます。この手順は、別のユーザーでも繰り返すことができます。
  4. 省略可: ブラウザでウェブアプリを更新します。ウェブアプリを右クリックして [ページのソースを表示] を選択し、表示名を検索します。サーバーから返された生の HTML ソースに表示されます。

レストランの情報を表示する

このウェブアプリには、レストランとレビューのモックデータが含まれています。

Cloud Firestore データベースにレストランのモックデータを挿入するには、2cf67d488d8e6332.png > [Add sample restaurants] を選択します。

レストラン リストがサーバーの実行時に読み込まれることを確認する

Next.js フレームワークを使用している場合、データがサーバーの実行時とクライアントサイドの実行時のどちらで読み込まれるかは明確でないことがあります。

サーバーの実行時にレストランのリスティングが読み込まれることを確認する手順は次のとおりです。

  1. ウェブアプリで DevTools を開き、JavaScript を無効にします。DevTools で JavaScript を無効にする
  2. ウェブアプリを更新します。レストランのリストはまだ読み込まれています。レストランの情報がサーバー レスポンスで返されます。JavaScript が有効になっている場合、レストランの情報はクライアントサイドの JavaScript コードを通じてハイドレーションされます。
  3. DevTools で、JavaScript を再度有効にします
  4. ウェブアプリで、27ca5d1e8ed8adfe.png > [Add sample restaurants] を選択します。スナップショット関数が正しく実装されている場合、ページを更新しなくてもレストランがリアルタイムで表示されます。

レストランのクチコミを追加する

レビューを追加して Cloud Firestore に挿入されたことを確認する手順は次のとおりです。

  1. ウェブアプリを更新し、ホームページからレストランを選択します。
  2. レストランのページで、[3e19beef78bb0d0e.png] をクリックします。
  3. 評価を選択してください。
  4. クチコミを書く。
  5. [送信] をクリックします。レビューはレビュー リストの一番上に表示されます。

9. 生成 AI を使用してレストランのレビューを要約する

このセクションでは、レビューの要約機能を追加します。これにより、ユーザーはすべてのレビューを読まなくても、レストランに対する他のユーザーの評価を簡単に把握できるようになります。

Gemini API キーを Cloud Secret Manager に保存する

App Hosting は Cloud Secret Manager と統合されているため、API キーなどの機密性の高い値を安全に保存できます。

  1. Gemini API を使用するには、API キーが必要です。Google AI Studio でキーを作成します
    プロンプトが表示されたら、この Codelab で使用しているプロジェクトと同じプロジェクトを選択します(バックグラウンドでは、Firebase プロジェクトは Google Cloud プロジェクトです)。
  2. IDX 内のターミナルで、次のコマンドを実行して新しいシークレットを作成します。
    firebase apphosting:secrets:set gemini-api-key
    
  3. シークレット値の入力を求められたら、Google AI Studio から Gemini API キーをコピーして貼り付けます。
  4. "To use this secret, your backend's service account must be granted access. Would you like to grant access now?"」というメッセージが表示されたら、Enter を押して [はい] を選択します。
  5. 新しいシークレットを apphosting.yaml に追加するかどうかを尋ねられたら、Y を入力して承諾し、Enter を押して環境変数名として GEMINI_API_KEY を選択します。

Gemini API キーが Cloud Secret Manager に安全に保存され、App Hosting バックエンドからアクセスできるようになりました。この値は、Google Cloud コンソールの Secrets Manager ダッシュボードでも確認できます。

  1. apphosting.yaml ファイルを開くと、Secret の名前は記録されていますが、値は記録されていません。次のようになります。
    runConfig:
        minInstances: 0
        maxInstances: 2
    env:
        # Get these values from the Firebase console
        - variable: NEXT_PUBLIC_FIREBASE_API_KEY
            value: xxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx
        - variable: NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN
            value: project-id.firebaseapp.com
        - variable: NEXT_PUBLIC_FIREBASE_PROJECT_ID
            value: project-id
        - variable: NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET
            value: project-id.firebasestorage.app
        - variable: NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID
            value: 111111111111
        - variable: NEXT_PUBLIC_FIREBASE_APP_ID
            value: 1:111111111111:web:aaaaaaaaaaaaaaaaaaaaaa
        - variable: GEMINI_API_KEY
            secret: gemini-api-key
    

レビューの概要コンポーネントを実装する

  1. IDX で src/components/Reviews/ReviewSummary.jsx を開きます。
  2. 関数全体を次の GeminiSummary に置き換えます。
    export async function GeminiSummary({ restaurantId }) {
        const { firebaseServerApp } = await getAuthenticatedAppForUser();
        const reviews = await getReviewsByRestaurantId(
            getFirestore(firebaseServerApp),
            restaurantId
        );
    
        const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
        const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash-lite",
        safety_settings: [
            {
            category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
            threshold: HarmBlockThreshold.BLOCK_NONE,
            },
        ],
        });
        const reviewSeparator = "@";
        const prompt = `
            Based on the following restaurant reviews,
            where each review is separated by a '${reviewSeparator}' character,
            create a one-sentence summary of what people think of the restaurant.
    
            Here are the reviews: ${reviews.map(review => review.text).join(reviewSeparator)}
        `;
    
        try {
            const result = await model.generateContent(prompt);
            const response = await result.response;
            const text = response.text();
    
            return (
                <div className="restaurant__review_summary">
                    <p>{text}</p>
                    <p> Summarized with Gemini</p>
                </div>
            );
        } catch (e) {
            console.error(e);
            return <p>Error contacting Gemini</p>;
        }
    }
    
  3. IDX 内のターミナルで次のコマンドを実行して、commit を作成し、GitHub リポジトリに push します。
    git commit -a -m "Use AI to summarize reviews"
    
    git push
    
  4. Firebase コンソールで [アプリホスティング] ページを開き、新しいロールアウトが完了するまで待ちます。
  5. ブラウザで、レストラン カードをクリックします。画面上部に、レストランのすべてのレビューの概要が 1 文で表示されます。
  6. 新しいクチコミを追加して、ページを更新します。概要が変更されます。

10. まとめ

これで完了です。このチュートリアルでは、Firebase App Hosting を使用して Next.js アプリをデプロイし、Gemini API を使用してテキストを要約する方法を学びました。具体的には、次のものを使用しました。

  • Firebase App Hosting。構成済みの GitHub ブランチに push するたびに Next.js コードを自動的にビルドしてデプロイします。
  • Cloud Secret Manager(App Hosting と統合)を使用して Gemini API キーを安全に保存し、アプリに生成 AI 機能を構築できるようにします。

詳細

完全版の Codelab「Firebase を Next.js アプリと統合する」で、Firebase Authentication、Cloud Firestore、Cloud Storage for Firebase をこのアプリに追加する方法をご覧ください。

他の Codelab もご覧ください。