Cloud Functions for Firebaseの始め方

Cloud Functionsの勉強を始めました。
以下、公式サイトとChatGPTを駆使して、ローカル開発環境の構築と簡単なサンプルコードの動作確認をしました。
※記事は、書きたい内容の目次をChatGPTに投げ、GPTからの文章を動作確認しながら、上手く動かない部分は修正・加筆したものになります。

# 想定読者
・Cloud Functionsをこれから使ってみたい人。
・ある程度は自分で調べならが開発を進められる人。（少し端折っている部分あるため）


# Cloud Functions for Firebaseとは？そもそもFirebaseって何？
Firebaseとは、
Googleが提供しているモバイルアプリやウェブアプリを作るためのツールやサービスの集まりです。
ゲームやチャットアプリ、ニュースアプリなど、さまざまなアプリを簡単に、早く作るために必要な機能が詰まっています。

その中の一つが「Cloud Functions for Firebase」です。
これは、プログラムのコードをクラウド上で動かすことができるサービスです。例えば、ユーザーがアプリで何かアクションを起こしたとき（例：メッセージを送る、写真をアップロードする）に、自動でコードが動き出して、必要な処理を行います。

# Cloud Functionsで何ができる？
Cloud Functionsを使うと、アプリのバックエンドで行うべき多くの処理を自動でこなすことができます。
例えば、ユーザーが新しい写真をアップロードしたときに、その写真を自動でサイズ変更する、またはメッセージが送られたときに通知を送る、といったことが可能です。

# Cloud Functionsを学ぶメリット
Cloud Functionsを学ぶことで、アプリ開発の幅が広がります。
コードを書いてアップロードするだけで、サーバーの管理やセキュリティの心配をせずに済むので、開発に集中できます。
また、使った分だけの料金で済むため、コストも抑えられます。

# 初心者でも分かるCloud Functionsの始め方
- Firebaseのウェブサイトにアクセスして、Googleアカウントでログインします
- 「プロジェクトを追加」をクリックし、プロジェクト名を入力してプロジェクトを作成します
![スクリーンショット 2024-03-10 13.31.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/2e61de10-5d40-1e7f-860b-f9b5bb8c3b3d.png)
表示される手順通りに進めて以下のようにプロジェクトを作成します。
![スクリーンショット 2024-03-10 13.35.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/be14f0ba-7fc5-ffcf-c007-1bd237631b81.png)

- コマンドラインを開き（WindowsではコマンドプロンプトやPowerShell、MacではTerminal）、以下のコマンドを入力してFirebase CLIをインストールします
```
npm install -g firebase-tools
```

- 以下コマンドをターミナル上で実行し、firebaseにログインできることを確認して下さい。
```
firebase login
```
ターミナル上で「✔  Success! Logged in as 自身のメールアドレス」が表示され、
ブラウザに以下画面が表示されたら成功です。
- ![スクリーンショット 2024-03-10 15.31.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/c46a0b2e-64ea-a0e1-4ff8-cff306048256.png)

# Blazeプラン（従量課金制）にアップデートする。
無料プランのままだと、作成したプロジェクトをFirebaseに
デプロイ（アップロード）する際エラーになります。

そのため事前有料プランに変更します。
先ほど作成したプロジェクトに行き、歯車マーク→「使用料と請求額」に移動します
![スクリーンショット 2024-03-10 16.43.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/3afd1421-5a17-7062-e8ec-1970988f1e14.png)
「詳細と設定」タブに移動し、「プラン変更」を押します
![スクリーンショット 2024-03-10 16.33.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/3d7fd40b-c8fc-1f51-d398-0b93d9ca014d.png)
「続行」ボタンを押し、
あとは画面の流れに沿って自分のクレジットカードなど支払いに関する情報に入力していきます。
![スクリーンショット 2024-03-10 16.35.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/6647e903-6166-48b3-b775-5220eaf8bd4c.png)

最終的に「課金予算の設定」が表示されるので、
課金予算をお好みで設定します。
![スクリーンショット 2024-03-10 16.36.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/5e5e7d29-c4cf-0253-ec01-1c38e614fd3e.png)

# Cloud Functionsでサンプルコード。簡単な動作確認
ここでは、ユーザーがデータベースにデータを追加したときに、自動でメッセージをログに記録する簡単なFunctionを作ります。

まずは、プロジェクトディレクトリを作成し、そのディレクトリ内で firebase init functions コマンドを実行します。
```
mkdir sample-firebase
cd sample-firebase
firebase init functions
```
上記コマンドを実行すると、以下のように４つほど、プロジェクトの選択を迫られます。
今回は一番上の「Use an existing project」を選択。
  - Use an existing project: ←今回はこちら
    - 既にFirebaseコンソールで作成してあるプロジェクトを選択したい場合はこれを選びます。この選択をすると、Firebase CLIはFirebaseアカウントに紐づいているプロジェクトのリストを表示し、その中からプロジェクトを選択できるようになります。
 - Create a new project: 
   - Firebaseにまだプロジェクトを作成していない場合、この選択肢を選んで新しいプロジェクトを作成できます。ただし、CLIから直接新しいプロジェクトを作成するにはFirebaseプラットフォームでの設定が必要になることがありますので、初心者の方はFirebaseのウェブサイトからプロジェクトを先に作成しておくことをおすすめします。
- Add Firebase to an existing Google Cloud Platform project: 
  - 既にGoogle Cloud Platform（GCP）でプロジェクトを持っていて、それをFirebaseプロジェクトとして使用したい場合に選びます。
- Don't set up a default project: 
  - 現時点で特定のプロジェクトをセットアップしたくない場合に選択します。このオプションは、一般的なFunctionsの設定を行うだけで、特定のプロジェクトに紐付けずに作業を進めたい場合に便利です。

プロジェクトを選択したら、次に使用する言語の選択になります。
今回はJavaScriptを選びます。
![スクリーンショット 2024-03-10 15.55.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/90db9247-4bbd-9513-7feb-0a8cefd46ae5.png)

言語を選択すると「Do you want to use ESLint to catch probable bugs and enforce style? (y/N) 」のように尋ねられます。
![スクリーンショット 2024-03-10 15.59.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/cb193faa-e0f6-b909-3e83-2fb269dac5ab.png)
- ESLintとは？
  - ESLintは、JavaScript（またはTypeScript）のコードを静的解析するためのツールで、コードに潜在的なエラーやバグがないかチェックし、一貫したコーディングスタイルを維持するのに役立ちます。開発者が独自のルールを設定することもできるため、チームプロジェクトにおいてコード品質を一定に保つのに非常に有効です。

  - 質問の意味
この質問でFirebase CLIは、プロジェクトにESLintを導入して、コードの品質管理を行うかどうかを聞いています。具体的には以下のようなメリットがあります：
    - 潜在的なバグの検出: 未使用の変数、無効な型の代入、構文エラーなど、コード内の問題を事前に検出できます。
    - コーディングスタイルの統一: インデントやセミコロンの使用、変数名の命名規則など、コーディングスタイルを統一するルールを設定できます。

今回は「y」を選びました。
※ESLintは結構うるさいやつなので、エラーでつまづきたくなく、早く動作確認したい人は「N」を選ぶのもいいかもしれません。実際にサービスを作ったりチーム開発する予定がある人は「y」を選びましょう。
- 続いて「? Do you want to install dependencies with npm now? (Y/n) 」と尋ねられます。
![スクリーンショット 2024-03-10 16.03.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/47cb76b9-7059-e1e2-305d-02e9acd77299.png)
npm（Node Package Manager）を使って今すぐに必要な依存関係（ライブラリやパッケージなど）をインストールするかどうかを尋ねています。

  - npmとは？
npmは、JavaScriptのためのパッケージマネージャーで、Node.jsのパッケージを管理するためのツールです。
npmを使用することで、開発に必要な外部ライブラリやツールを簡単にインストールし、プロジェクトに追加することができます。

  - 依存関係（Dependencies）とは？
依存関係とは、プロジェクトが正しく動作するために必要な外部のコードやライブラリのことです。
たとえば、データベースとのやりとりを簡単にするライブラリや、データを形式化するためのツールなどがあります。

 「n」を押すと自分で「npm install」で必要なものをインストールする必要があるため、
 今回は「Y」を選択しましょう。

「✔  Firebase initialization complete!」と表示されたら成功です。
 ![スクリーンショット 2024-03-10 16.09.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/c54e107c-3d4c-8cd1-eaaf-51eec0c0cd5f.png)

続いてプロジェクト配下にある「functions/index.js」ファイルを開き、すべてのコードを削除した後、以下コードを記載します。
```javascript:index.js
// 必要なFirebase FunctionsとAdmin SDKをインポートします
const functions = require("firebase-functions");
const admin = require("firebase-admin");
// Firebaseの管理機能を実際に使えるようになります。この行がないと、次の行でデータベースにアクセスしたり、何か操作をしたりすることができません。
admin.initializeApp();
/* この行は、Firestore内のmessagesという場所に新しい情報（ドキュメント）が追加されたときに、自動で動き出すプログラム（Function）を設定しています。
{messageId}は追加される各メッセージのユニークなIDを表しており、それによって特定のメッセージを識別できます。*/
exports.logNewMessage = functions.firestore
    .document("messages/{messageId}")
    .onCreate((snap, context) => {
      // 新しく追加されたメッセージの内容を取り出しています。snapは追加されたメッセージの情報を含んでいるオブジェクトで、.data()メソッドを使うことでその内容を取得できます。
      const newValue = snap.data();

      // メッセージ内容をコンソール（コンピューターの画面）に表示します
      console.log("New message added:", newValue);

      // このFunctionは情報を取得してログに表示するだけで、特に外部に何かを送り返す必要はありません。そのため、nullを返してFunctionの終了を示しています
      return null;
    });
```
変更を保存したら、以下コマンドでFirebaseにデプロイ（クラウド上に反映）します。
```
firebase deploy --only functions
```
「✔  Deploy complete!」と表示されたら完了です。

「Project Console: 」の後に表示されるURL先にアクセスしましょう。

![スクリーンショット 2024-03-10 16.51.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/9b1f60f5-55e9-0f39-592d-4caefb63c64b.png)

アクセスしたら、「Firesotre Database」画面に移動。「データベースの作成」をクリック
![スクリーンショット 2024-03-10 16.52.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/a193d1b4-9dff-1e61-a0eb-874c8acff237.png)

ロケーションを「asia-northeast1(Tokyo)」を選択
![スクリーンショット 2024-03-10 16.53.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/b11109ca-37d9-b322-141e-a4c765ab04ef.png)

テストモードは初期状態でインターネット上の誰からでもアクセスできるようなので、
「本番環境モード」を選択します。
![スクリーンショット 2024-03-10 16.56.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/6b9021a6-7ee2-e21d-d048-0124907e7ce9.png)

- テストモード
  - アクセス許可: 
  テストモードでは、デフォルトでインターネット上の誰でも作成したデータベースにアクセスして、読み書きが可能になります。これにより、開発の初期段階でアプリケーションの構築とテストを簡単に行えます。
  - 使用目的: 
  主に開発の早い段階や、プロトタイピング、テストのために使用します。
  このモードでは、アプリケーションが正しく動作することを素早く確認できます。
  - リスク: 
  セキュリティルールが緩いため、悪意のあるユーザーがデータを読んだり変更したりするリスクがあります。
  そのため、短期間のみ使用し、公開前には本番環境モードに切り替えることが推奨されます。
- 本番環境モード
  - アクセス許可: 
  本番環境モードでは、デフォルトで全ての外部アクセスが禁止され、明示的に許可されたリクエストのみがデータベースの読み書きを行えるようになります。
  セキュリティルールを通じて、アクセスを厳格に管理します。
  - 使用目的: 
  アプリケーションを公開し、実際のユーザーに使用してもらう際に適しています。
  データの安全性を確保し、不正アクセスから保護するためのルールを設定できます。
  - 設定必要性: 
  本番環境で使用する前に、適切なセキュリティルールを設定する必要があります。
  これには、誰がデータにアクセスできるか、どのようなデータ操作が許可されるかを定義する作業が含まれます。

データベースが作成されるので、以下画面で「コレクションを開始」をクリック!

![スクリーンショット 2024-03-10 17.03.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/61972587-af25-e0f6-265b-ad9de0ed757f.png)

コレクションIDを入力（任意の値）
![スクリーンショット 2024-03-10 17.04.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/ad85a0ae-3d86-10a3-0e90-86c478482a93.png)

フィールド名text、値にHello, Firebase!を設定（任意の値）
![スクリーンショット 2024-03-10 17.05.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/3645a55a-a99e-d36f-2b4c-ac9b960277e4.png)

コレクションが作成されるのを確認
![スクリーンショット 2024-03-10 17.05.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/0cd9e2a6-633d-7d4a-0d83-74b5144bb0b5.png)

続いて、ログが出力されるのを確認します。
サイドバーのFiresotre Databaseをクリック
![スクリーンショット 2024-03-10 17.06.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/645a1958-ecc9-c939-d42e-00f0839b6653.png)

「ログビュー」をクリック
![スクリーンショット 2024-03-10 17.08.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/18f36c19-06b1-e770-5450-9fbec07411d4.png)

ログ　エクスプローラ画面で
「New message added: { text: 'Hello Firebase!' }」と表示されたら成功です。
![スクリーンショット 2024-03-10 17.11.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2640031/843ad3fe-c479-189e-f8d9-32be20b4b257.png)


# まとめ
・Firebaseとその中のサービスであるCloud Functions for Firebaseについて学んだ
・Firebaseはアプリ開発を簡単に早く進めるためのツールやサービスの集まりであり、Cloud Functionsはその中でプログラムのコードをクラウド上で動かすことができる便利なサービス
・Cloud Functionsを使うことで、アプリのバックエンド処理を簡単に自動化でき、開発の効率を大きく上げることが可能になる

今回の記事作成を通じて、Cloud Functionsの基本的な使い方と簡単な動作確認を行うことができました。今後より使いこなせるよう勉強を続けたいと思います。

また、私自身Cloud Functionsの学習1日目の初学者であるため、当該記事には荒が目立つかもしれません。（勉強しながら記事を書いた）
学習を続け、今後はもっと質の高い記事を書けたらと思います。

# 参考文献
Firebase公式サイト: https://firebase.google.com/?hl=ja
Firebaseのドキュメント: https://firebase.google.com/docs?hl=ja
Cloud Functions for Firebaseのガイド: https://firebase.google.com/docs/functions?hl=ja