0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter】Cloud Functions for Firebaseの基本

Last updated at Posted at 2024-10-17

1. はじめに

FlutterとFirebaseは、モバイルアプリやウェブアプリの開発において強力なツールです。その中でCloud Functions for Firebaseは、バックエンドの処理を簡単にサーバーレスで実行できるサービスです。本記事では、Cloud Functions for Firebaseの基本的な使い方と、Flutterとの連携について解説していきます。

2. Cloud Functionsとは

Cloud Functions for Firebaseは、Google Cloudが提供するサーバーレスコンピューティングサービスです。サーバーレスとは、開発者がサーバーの管理・運用を行う必要がなく、ソースコードの記述のみでバックエンドの機能を実現できる仕組みです。Cloud Functionsでは、イベントがトリガーされた際に、バックエンドの処理を自動で実行することができます。

具体的に、以下のような用途で活用できます:

  • Firebase AuthenticationやCloud Firestoreのデータベース変更に応じて処理を実行
  • HTTPリクエストに応じて処理を実行
  • 定期的なスケジュールに従って自動で処理を実行

3. 料金プラン

Firebaseには、SparkプランとBlazeプランがあります。Cloud Functions for Firebaseを利用するには、Blazeプランを使用する必要があります。Blazeプランはクレジットカード登録が必要ですが、Blazeプランにしただけで料金が発生することはないので安心してください。無料枠を超えた利用をした場合にのみ、料金がかかってきます。Firebaseは無料枠が広いので、普通に使っている分には料金がかかることは少ないです。

以下は、Cloud Functions for Firebaseの無料枠に関する表です。

無料枠項目 無料枠内容
リクエスト数 200万リクエスト/月
CPU時間 400,000 GHz-秒/月
インバウンドデータ転送 5GB/月
アウトバウンドデータ転送 5GB/月
並行実行 最大1,000並行リクエストまで無料
スケジューリング 無制限

補足:

  • リクエスト数やCPU時間、データ転送量に関しては、月単位で無料枠があります
  • 並行実行は、並行で1,000リクエストまで無料で処理が可能です
  • スケジュール実行に関しては、月内の回数に制限なく無料で実行できます。

多くの小規模なアプリケーションや開発段階のプロジェクトでは、無料枠の範囲内で運用できることが多いです。

4. Cloud Functionのバージョン

Cloud Functionsには、第1世代第2世代の2つのバージョンがあります。それぞれに特徴があり、用途に応じて使い分ける必要があります。

以下は、Cloud Functions for Firebaseの第1世代と第2世代の比較表です。

比較項目 第1世代 第2世代
最大メモリ割当て 2GB 16GB
最大CPU 1 vCPU 8 vCPU
並行処理 シングルリクエスト 並行処理が可能(最大1000リクエストまで)
関数の起動時間(Cold Start) 遅い 高速
料金 低性能のため安価で済む可能性が高い 高性能で並行処理が可能なため、高額になる可能性がある
スケール上限 1000 関数インスタンス 100,000 関数インスタンス
機能 一通りの機能を利用可能 一通りの機能を利用可能
リージョン 特定リージョン 多くのリージョンに対応

第2世代のCloud Functionsは、高性能、並行処理、スケーリングなどが大幅に向上しており、基本的には第2世代を利用しておけば問題ないと思います。本記事では、第2世代を利用して解説していきます。

5. Cloud Functionsのセットアップ

Cloud Functions for Firebaseを使用するためには、Firebaseプロジェクトを作成し、Cloud Functionsのセットアップを行う必要があります。本セクションでは、セットアップの基本的な流れについて説明します。

1. Firebaseプロジェクトを作成

Firebase Console (https://console.firebase.google.com) にアクセスし、「プロジェクトを作成」 を選択して、プロジェクトを作成します。

image.png

2. FirebaseとFlutterのプロジェクトを連携

以下のFlutterアイコンを選択すると、FirebaseとFlutterのプロジェクトを連携するためのガイドが表示されますので、ガイドに沿って設定をしてください。

image.png

3. CloudFunctionsのセットアップ

Cloud Functionsのページに移動します。

image.png

料金プランを、Blazeプランに設定します。
image.png

料金プラン変更後、「はじめる」を選択します。

image.png

以下のポップアップが表示されますので、Firebaseツールをインストールしておきます。

image.png

任意のディレクトリで以下のコマンドを実行し、次のページに進みます。

npm install -g firebase-tools

以下のコマンドのうち、firebase initのみ実行し「終了」を選択します。

スクリーンショット 2024-10-17 21.21.36.png

Flutterプロジェクトのルートで、以下のコマンドを実行します。

firebase init

上記のコマンドを実行すると、いくつか質問されるので回答していきます。

# 質問1
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. Functions: 
# 回答
Configure a Cloud Functions directory and its files

# 質問2
? Please select an option:
# 回答
Use an existing project

# 質問3
? Select a default Firebase project for this directory:
# 回答
your-firebase-project

# 質問4
? What language would you like to use to write Cloud Functions?
# 回答
JavaScript

# 質問5
? Do you want to use ESLint to catch probable bugs and enforce style?
# 回答
No

# 質問6
? Do you want to install dependencies with npm now?
# 回答
Yes

上記のコマンド実行後、functions フォルダが生成されます。

4. Hello World

関数を作成(ソースコードを記述)し、デプロイ(Firebaseにアップロード)してみます。functions/index.jsに以下のコードを記述してみましょう。

// Cloud Functions 第2世代(公式で推奨)
const functions = require('firebase-functions/v2');

// 外部からアクセスできる関数を定義
exports.helloWorld = functions.https.onRequest((request, response) => {
  // Firebaseのログに出力
  functions.logger.info("Hello logs!", {structuredData: true});
  // レスポンスとして値を返す
  response.send("Hello from Firebase!");
});

Firebaseツールで、関数をFirebaseにアップロードします。

firebase deploy --only functions

これで、helloWorld 関数がデプロイされ、指定されたURLで呼び出すことができます。

5. 動作確認

関数のデプロイが完了すると、Cloud Functionsのページで関数が表示されます。また、ここに表示されたURLにアクセスし、「Hello from Firebase!」というメッセージが表示されるか確認しておきましょう。

image.png

6. 実装

本セクションでは、Cloud Functionsを具体的にFlutterアプリと連携させる際、よく使う実装パターンについて解説します。

1. HTTP リクエスト経由で関数を呼び出す

HTTPリクエストを使用して、Flutterアプリや外部のサービスからCloud Functionsを呼び出すことができます。

Firebaseの実装:

functions/index.jsに、HTTPトリガーを利用した関数を作成します。
functions.https.onRequestで関数を定義します。

const functions = require("firebase-functions/v2");

exports.helloWorld = functions.https.onRequest((request, response) => {
  functions.logger.info("Hello logs!", {structuredData: true});
  const result = {
    title: "Hello",
    data: "World"
  };
  
  // JSON形式で応答を返す
  response.status(200).json(result);
});

Flutterから呼び出す際の実装:

FlutterからCloud Functionsを呼び出す場合、httpパッケージを使って、HTTPリクエストを送信します。

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<void> fetchData() async {
  final response = await http.get(Uri.parse('<Cloud Functions URL>'));

  if (response.statusCode == 200) {
    var data = json.decode(response.body);
    print(data); // 取得したデータを表示
  } else {
    print('Failed to load data');
  }
}

2. スケジュールに従って関数を呼び出す

定期的に実行する必要があるタスク(例:毎日バックアップを作成するなど)をCloud Functionsで自動化することができます。

Firebaseの実装:

毎日0時に関数を実行する:

functions/index.jsに以下の通り実装します。

const functions = require("firebase-functions/v2");
const {onSchedule} = require("firebase-functions/v2/scheduler");

exports.time1 = onSchedule({schedule: 'every day 00:00', timeZone: 'Asia/Tokyo'}, async (event) => {
  functions.logger.info("every day 00:00", {structuredData: true});
});
  • 3分おきに関数を実行する
const functions = require("firebase-functions/v2");
const {onSchedule} = require("firebase-functions/v2/scheduler");

exports.time2 = onSchedule({schedule: 'every 3 minutes'}, async (event) => {
  functions.logger.info("every 3 minutes", {structuredData: true});
});

3. Firebase Authentication トリガー

ユーザーの認証状態(新規登録、ログイン、削除など)に応じて特定の処理を実行することができます。

Firebaseの実装:

ユーザが新規登録したときに、Cloud Firestoreにuid, Emailを登録する関数を実装します。

// v1 APIを使用
const functions = require("firebase-functions/v1");
// firebase-adminはバックエンドのサーバ環境で、Firebaseの各サービス(Authentication、Firestore、Realtime Database、Cloud Messagingなど)を直接操作可能
const admin = require("firebase-admin");
admin.initializeApp();

exports.onUserCreate = functions.auth.user().onCreate((userRecord, _context) => {
  const user_id = userRecord.uid;
  const email = userRecord.email;
  console.log(user_id);
  console.log(email);

  // 必要な処理をここに記述します
  // 例: Cloud Firestoreにユーザーデータを保存するなど
  return admin.firestore().collection("users").doc(user_id).set({
    email: email,
    createdAt: admin.firestore.FieldValue.serverTimestamp(),
  });
});

4. Cloud Firestore トリガー

Firestoreのデータ変更に応じて自動的に処理を実行することができます。例えば、ドキュメントの作成、更新、削除時に動作する関数を作成可能です。

Firebaseの実装:

Firestoreのドキュメント作成時に動作する関数を作成します。

const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

exports.onCreateTrigger = onDocumentCreated("users/{docId}", (event) => {
  const snapshot = event.data;
  const data = snapshot.data();
  console.log(data);
  console.log(event.params.docId);
});

参考

Cloud FunctionsのCLIコマンドは、開発やデプロイの際に頻繁に利用します。

関数のリストを表示
firebase functions:list

┌────────────┬─────────┬─────────┬─────────────┬────────┬──────────┐
│ Function   │ Version │ Trigger │ Location    │ Memory │ Runtime  │
├────────────┼─────────┼─────────┼─────────────┼────────┼──────────┤
│ helloWorld │ v1      │ https   │ us-central1 │ 256    │ nodejs18 │
└────────────┴─────────┴─────────┴─────────────┴────────┴──────────┘
全ての関数をデプロイ
firebase deploy # or
firebase deploy --only functions
特定の関数のみデプロイ
firebase deploy --only functions:func1
関数の削除
firebase functions:delete func1 func2

おわりに

Cloud Functions for Firebaseを活用することで、Flutterアプリケーションとバックエンド処理をスムーズに連携させることが可能です。サーバーレスのメリットを活かし、サーバーの管理や運用を気にせず、アプリケーションの開発に集中できる点が非常に魅力的です。加えて、トリガーベースの関数や定期実行タスクを簡単に実装できるため、リアルタイムな応答や自動化された処理を手軽に取り入れることができます。本記事を通じて、Cloud FunctionsとFlutterの連携方法や、基本的な実装パターンについて理解を深めていただけたなら幸いです。これからさらにアプリを進化させるための一助となれば嬉しいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?