🎯

dart_firebase_adminの紹介とCloud FunctionsをDartで書きたい!

2023/12/23に公開

Firebase Admin SDKは、Firebaseのサービスをサーバーサイドから操作するためのツールです。特にdart_firebase_adminは、DartでFirebaseの機能を利用するためのパッケージです。この記事では、このパッケージの基本的な使い方と機能について解説します。

https://pub.dev/packages/dart_firebase_admin
https://github.com/invertase/dart_firebase_admin

dart_firebase_adminの紹介

パッケージのインストール

以下を実行してパッケージをインストールします。

flutter pub add dart_firebase_admin

Firebaseプロジェクトの設定

Firebaseプロジェクトを作成し、サービスアカウントの秘密鍵を生成します。Firebaseコンソールから秘密鍵のJSONファイルをダウンロードし、アプリケーションからアクセスできる場所に保存します。

Firebase Adminの初期化

import 'package:firebase_admin/firebase_admin.dart';

void main() {
  final admin = FirebaseAdminApp.initializeApp(
    '<your project name>',
    Credential.fromServiceAccount(
      File('<path to your service-account.json file>'),
    ),
  );
}

このコードは、Firebase Admin SDKを初期化する基本的な方法です。AppOptionsには、Firebaseプロジェクトの認証情報を含むJSONファイルのパスを指定します。
初期化方法として3種類の中から適切なものを選べます。

  1. 上記のファイル読み込みする方法(アプリで使っているように簡単に使える)
  2. 実行環境でEXPORTされた環境変数を使って初期化する方法(コード上で秘匿情報を扱わなくていい)
  final admin = FirebaseAdminApp.initializeApp(
    '<your project name>',
    Credential.fromApplicationDefaultCredentials(),
  );
  1. 認証情報を含むJSONファイルから特定の情報を文字列として直接読み込む方法(ファイルシステムを使えない環境でも簡単扱える)
  final admin = FirebaseAdminApp.initializeApp(
    '<your project name>',
    Credential.fromServiceAccountParams(
        clientId: <clientId>,
        privateKey: <privateKey>,
        clientEmail: <clientEmail>,
    ),
  );

様々な方法で初期化できます。

Firestoreの操作

Firestoreへのアクセスは以下のように行います。
Firestoreの多様な機能がサポートされており、ドキュメントの追加、取得、更新、削除など基本的な操作が可能です。また、クエリ機能も充実しており、様々な検索条件を設定することができます。

ほとんどのメソッドは実装済みであり、既に実用可能なレベルだと思います。

1 2
import 'package:dart_firebase_admin/dart_firebase_admin.dart';
import 'package:dart_firebase_admin/firestore.dart';

void main() {
  final admin = FirebaseAdminApp.initializeApp(
    '<your project name>',
    Credential.fromApplicationDefaultCredentials(),
  );
  final firestore = Firestore(admin);
  firestore.doc('hello/world').get();
}
final collection = firestore.collection('users');
final adults = collection.where('age', WhereFilter.greaterThan, 18);
final adultsSnapshot = await adults.get();
for (final adult in adultsSnapshot.docs) {
  print(adult.data()['age']);
}

このように普段Flutterで利用する書き味そのままで利用することができます

Authenticationの操作

Firebase Authenticationを使うこともできます。
ユーザーの作成、情報の取得、更新、削除などが可能です。

こちらも、ほとんどのメソッドは実装済みであり、既に実用可能だと思います。

import 'package:dart_firebase_admin/auth.dart';
import 'package:dart_firebase_admin/dart_firebase_admin.dart';

void main() {
  final admin = FirebaseAdminApp.initializeApp(
    '<your project name>',
    Credential.fromServiceAccount(
      File('<path to your service-account.json file>'),
    ),
  );
  final auth = Auth(admin);
  await auth.deleteUser("< UserId >");

  // その他認証関連の操作
}

dart_firebase_adminまとめ

dart_firebase_adminパッケージは、Dart言語でFirebaseの各種機能を利用するための強力なツールです。Firebaseプロジェクトの管理、データベース操作、認証サービスの利用などが可能で、サーバーサイドの開発を強力にサポートします。

DartでCloud Functionsを書きたい!

Dartでのサーバーサイド構築の方法として数個候補が上がります。

functions-framework-dart (GCP)

https://github.com/GoogleCloudPlatform/functions-framework-dart
Googleから出されているfunctions-framework-dartがあります。
現状は、CloudRunにデプロイすることになるのでCloudFunctionsと同等の扱いをすることはできません。ただ、CloudRunとしてCloud FunctionsのRESTAPIとしての機能は簡単に扱うことができます。

レポジトリのコミットを見ると比較的活発に開発されており、名前にfunctionsとあるのも含め、将来的にはCloudFunctionsとして直接deployできるのようになるのではないかと予想しています。
また、自身では試していませんがドキュメントに以下の記述があり、Firestore Triggerで動かすことも可能かと思います。

Automatically unmarshal events conforming to the CloudEvents spec

Firestore Triggerなどでも使われているCloudEventを使うことができるので適切に設定さえすれば、現状のCloud Functionsでよく使われる部分は、全て利用可能になるかと思います。CloudEventに関してのexampleも用意されています。

dart_edge (Vercel,Cloudflare,Supabase)

https://github.com/invertase/dart_edge
https://docs.dartedge.dev/
invertaseから出されている、高速なアクセス,レスポンスが可能なedge環境にAPIをdeployするdart_edgeがあります。
dart_edgeが持つadapterを使ってedge環境へdeployできるサービス各々向けに調整され、各サービスが持つ機能にアクセスできます
特に私自身が推しているCloudflareでは、コールドスタート無しの超高速なレスポンスやキャッシュなどを細かく調整できる機能にアクセスし、高速化やコスト削減を狙えます。
こちらは、Cloud Functionsの代わりに成り代わるわけではありませんが、deploy先プラットフォームの優位性を活用することができます。

私が検証用に作った二つのサンプルを挙げておきます

  1. Cloudflareでdart_firebase_adminを使うサンプル

https://github.com/akaboshinit/sandbox_dart/tree/main/dart_edge/firebase_admin
2. Cloudflareの機能であるHTMLRewriterを使って特定サイトのOGPを書き換えるプロキシサンプル

https://github.com/akaboshinit/sandbox_dart/tree/main/dart_edge/html_rewriter

deployサービスに合わせ使いたいサーバーフレームワーク

上記のdeployができるサービスに合わせて以下のサーバーフレームワークを活用できれば、より柔軟に実装ができます。

  • dart_frog (Very Good Ventures)
    開発時のディレクトリ構成をそのままAPIのRoutingにしてしまう簡単なAPI構築
  • shelf (dart-lang)
    Dart謹製の古くから有る成熟したサーバーフレームワーク
    モジュール方式で有象無象多種多様なモジュールたち

DartでCloud Functionsを書きたい!まとめ

Dartをメインとして書くのなら現在Cloud Functionsを真っ直ぐ綺麗に書く方法は、まだありません。少し抽象度の高いCloud Runや別サービスのedgeを使ってAPI部分のみ書くことができます。

まとめ

Cloud Functionsの取り回しの良さをそのままDartで書くことができないのは残念です。ですが、dart_firebase_adminやfunctions-framework-dartのなどなどサーバー関連の開発が進み充実していく中で、全てをDartで書く夢は目前のようにも思えます。
皆さんでサーバー系パッケージを盛り上げ、Dartで世界を征服しましょう。

Discussion