ついに出た！FirebaseでPostgreSQLが使えるように！

# はじめに

Google I/O 2024でFirebaseに関わるアップデートがいろいろ出ました。
気になるアップデートいっぱいあったんですがその中でも予想外かつ興味があったFirebase Data Connectを取り上げてみようと思います。

まだまだ始まったばかりなので、この記事を更新していく形で追っていこうと思います。

# Firebase Data Connectとは？

Cloud SQL for PostgreSQL、タイプセーフなモバイル SDK およびウェブ SDK を使用して安全でスケーラブルなアプリを作成するデベロッパー向けの Firebase 初のリレーショナル データベース ソリューションと公式ではうたっています。

https://firebase.google.com/docs/data-connect?hl=ja

FirebaseでRDBSが使えるようになるということですね。

FirebaseはFirestoreとRealtime Databaseという２種類のデータベースをすでに持っていますが、それぞれNoSQLで今までRDBMSでシステムを組んできている人たちにとってはちょっとした導入障壁になっていたと思います。

それぞれかなりイケてるNoSQLなんですが、かなり使い慣れていると思っている自分でさえ、それでもRDBMSだったら簡単にできるのになーと思うことはちょくちょくありました。

そこで今回のアップデートは、NoSQLでFirebase利用を躊躇していた人と、ちょっとここだけはRDBMS使いたいと思ってた人にとって非常に嬉しいアップデートだと思います！

# Firebase Data Connectを使ってみた

## まずは申請

Firebase Data Connectは、今のところ限定公開プレビューという状態でFirebaseプロジェクトを開いても使えない状態です。

![CleanShot_2024-05-22_at_14.26.03_2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341912/e9bd9b1b-1877-4162-1564-84066056f4f3.png)

Firebase Consoleにメニューは出てきていると思いますが、押してもこんな状態ですね。
ここから詳細を押してまずは申請を行いましょう。いくつか個人情報を入力すると申請が完了します。
そこから、数日待つとメールが来て利用できるようになりました。

ただ、どれくらいの期間かかるかは、Googleさんのみぞ知るところなので、申請してから気長に待つ必要があります。


## 実際に使ってみる

ここから以下のサイトを見て、環境を整えていきます。

https://firebase.google.com/docs/data-connect/quickstart?hl=ja

コーディング環境としてVS CodeとIDXというものが提供されています。
IDXは今回のアップデートで利用できるようになったウェブ上でVS Codeのようなエディターが使えるサービスのようです。

私は使い慣れているVS Codeで始めました。

### コーディングの流れ

詳しくはquickstartを見て貰えばわかるのですが、簡単に具体的な流れも書いていきます。

`firebase init dataconnect -P プロジェクト名`を実行するといくつかのファイルが自動生成されます。

```
dataconnect
├── connector
│   ├── connector.yaml
│   ├── mutations.gql
│   └── queries.gql
├── dataconnect.yaml
└── schema
    └── schema.gql
```

このファイルをいじっていけばいいみたいです。
RDBなのでまずは表定義をしていきます。

`schema/schema.ggl`に書いていきます。自動生成された時点でいくつかの定義がコメントで作られているので、それを外して保存してみます。

```graphql
type User @table(key: "uid") {
	uid: String!
	name: String!
	address: String!
}

type Email @table {
	subject: String!
	sent: Date!
	text: String!
	from: User!
}
```

Userの方には`(key: "uid")`が書かれていますが、これをつけると主キーがそれに置き換わるみたいで、つけないと自動で`id`がつけられて、UUIDで自動採番されるみたいです。

実際にデプロイしてみます。エクステンションのDeployボタンでできます。
そうすると表がCloudSQL内に存在しないので、`Execute changes`と選択肢が出てきて、データベースを作成するかどうかを聞いてきます。その上には実行されるSQLも記載されています。

```sql
/** create "user" table*/
CREATE TABLE "public"."user" (
  "uid" text NOT NULL,
  "address" text NOT NULL,
  "name" text NOT NULL,
  PRIMARY KEY ("uid")
)
/** create "email" table*/
CREATE TABLE "public"."email" (
  "id" uuid NOT NULL DEFAULT uuid_generate_v4 (),
  "from_uid" text NOT NULL,
  "sent" date NOT NULL,
  "subject" text NOT NULL,
  "text" text NOT NULL,
  PRIMARY KEY ("id"),
  CONSTRAINT "email_from_uid_fkey" FOREIGN KEY ("from_uid") REFERENCES "public"."user" ("uid")
)
```

こんな感じで出てきます。表の定義を変更して同じコマンドを実行すると、その差分を計算してSQLを自動発行してくれます。
試しに`User`テーブル`role`カラムを追加します。

```graphql
type User @table(key: "uid") {
	uid: String!
	name: String!
	address: String!
    role: String!
}
```

するとSQLは以下のようになりました。

```sql
/** modify "user" table*/
ALTER TABLE "public"."user"
ADD COLUMN "role" text NOT NULL
```

便利ですね。
ここでFirebase Consoleを確認すると以下のような表示がされます。

![スクリーンショット 2024-05-24 6.26.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341912/20b55108-d408-27e4-1f63-3087275d1d72.png)

ここも便利になっています。
`データを表示`というボタンがあるので、押してみます。

![スクリーンショット 2024-05-24 6.28.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341912/6e1e1025-d30d-d2b0-2679-e7ab54aa6c8d.png)

おお、ここはGraphQLを書く必要があるようです・・・。
ただ、ここでわかるのはスキーマを定義した時点でinsertやselectなど一般的な操作に必要なqueryとmutationは自動生成されているようです。
これを使えば、データの表示、追加も行えるようになっています。

## ハマったところ

少しだけハマったので、そこをお伝えしておきます。
限定公開プレビューなのでまだまだ荒削り感があります。アップデートもあると思うので、ここについては更新があるたびに直していこうと思います。

- 環境構築でエラーが出る
新規プロジェクトであればサクッと`firebase init`コマンドもVS Codeのエクステンションも動いたのですが、既存プロジェクトでfirebase.jsonが複数あったり、ルートディレクトリ内にない場合は、どちらもうまく機能しませんでした。

- Cloud SQLを直接触れない
Data Connectを有効にして進めると自動でCloud SQLが作成されます。
通常、GCP ConsoleからSQLを使ったアクセスが可能になるのですが、アクセスするためのユーザーアカウントのパスワード等がわからないため、存在はしても中身を直接みることができませんでした。`firebase init`でいくつかのファイルが作成されるのですが、そこに情報もないので手詰まりな感じです。

- エクステンションのEmulator Startが機能しない
エクステンションにEmulator Startというボタンがあるので、それでEmulatorが動き出す仕組みになっています。ローカルのPostgreSQLを使うようになるので、そもそもそこの構築ができていないとエラーになります。さらにアクセスするときにData Connectで指定したデータベース、ロール等が必要なので、自分で追加する必要がありました。そしてパスワードなしでログインしないといけないので、pg_hba.confを更新してパスワードなしでログインできるように設定変更する必要もありました。

- JavaScriptのパッケージのバージョン注意
通常リリースされているバージョンだと、Data Connectに関わる関数が利用できませんでした。
専用のバージョンが出ていたのでそちらのインストールが必要です。

```sh
npm install firebase@10.12.0-dataconnect-preview.388b61c7e
```

# 使ってみてわかったこと

今まで公表されている情報から読み取り切れなかったかつ使ってみてわかったことを書いておきます。

- リアルタイム更新の機能は、今はない
Firestore/Realtime Databaseが現状でも唯一無二な部分がこのリアルタイム更新の部分だと思います。GraphQLでもサブスクリプションとして機能は存在していますが、そのインフラをスケーラビリティも含めて考えるとかなり難しいため、自前でやるのが厳しい部分です。Data ConnectはGraphQLを採用しているため、ここもできるかな？と期待していましたが今はできませんでした。ただ、ここはかなり要望がでてきそうな部分なので、Googleさんはやってくれるでしょう！みんなで要望を出していきましょう！

- SQLは書かない
~~今触ってみたところなので、まだわかってないだけの可能性はありますが、SQLを書いて開発することはなさそうです。すべてGraphQLを書いて操作します。それは、マイグレーションだけでなく、データ操作も含めてすべてGraphQLを使うことになります。~~
基本的にはGraphQLを書いて対応していくことになります。
ただ、PostgreSQLのviewを使うことができるようになっているので、そこでSQLを書くことができました！
書く時は`table`のところを`view`と書くようです。
```graphql
type OderStat @view(sql: """
  SELECT
    COUNT(*) AS count,
    AVG(total) AS average_total,
    FROM "order"
""") {
  count: Int
  averageTotal: Float
}
```

# 今のところの感想

期待感はあるけど今はちょっと物足りないというのが正直な感想です。
普通にCloud Functionsを使ってCloud SQLを触った方がいろいろできるなってところなので。

Firestoreとの連携の強化、リアルタイム更新はくらいはなるべく早くほしいところです！