Firebase Data Connectを使ってみよう
Firebase で RDB (PostgreSQL) が使えるData Connect
今のところプレビュー版だけど、一旦使ってみる
これまで Firebase の中でDB使おうと思ったらFirestore (NoSQL) しかなかったので、早くGAしてほしい
スタータードキュメントがほぼ同じようなの2つあるけど違うのかな?
↑こっち(後者)を参照しながら進めてみる
Blaze プランが必要
無料プランのSparkプランだと使わせてもらえない。
従量課金のBlazeプランに入る必要がある。
まあ多少はお金かかってもいいのでプランを上げる。
あとData Connectについては3ヶ月無料(?)的なことが書いてあったはず(スクショ撮っておけばよかった)
※正確な内容は各自お調べください
注: Spark プラン プロジェクトで Data Connect を試す場合は、このローカルのクイックスタート ガイドをご覧ください。このガイドでは、エミュレータとローカル データベースを使用してローカルでプロトタイプを作成します。代わりに、Blaze プラン プロジェクトに Data Connect を追加してサービスと Cloud SQL データベースを設定する場合は、本番環境のスタートガイドをお試しください。
https://firebase.google.com/docs/data-connect/quickstart-local
ローカル環境のエミュレータで試すだけならSparkでも行けるらしい?
VSCode拡張
Data Connect のVSCode拡張がある
インストールして、拡張機能のパネルからGoogleログインすると、プロジェクトのセットアップが実行できる
「Start emulators」でエミュレータ実行。ローカルでData Connectを起動できる。
VSCode拡張でセットアップするとファイルが作られる
├─.firebaserc
├─.gitignore
├─firebase.json
│
├─.firebase
│ .graphqlrc
│
└─dataconnect
│ dataconnect.yaml
│
├─.dataconnect
│ └─schema
│ │ prelude.gql
│ │
│ └─main
├─connector
│ connector.yaml
│ mutations.gql
│ queries.gql
│
└─schema
schema.gql
スキーマ定義
スキーマは /dataconnect/schema/schema.gql
のファイルで定義する。
セットアップ時に作られたファイルにはコメントアウトされた状態でサンプルコードが書いてあるので、コメントアウトを外す。
クエリ実行
拡張機能によって、 type
の定義の上に「Add data」「Read Data」というボタンが現れる(便利の波動を感じる)
このボタンは「CodeLens ボタン」と言うらしい(この拡張機能に限った名前ではなく、コード中に挿入される表示が CodeLens っていうことなのかな?)
「Add data」を押すとインサートを実行するためのmutationが書かれたgqlファイルが生成される(お手軽~~~!)
保存すると dataconnect/MovieMetadata_insert.gql
として保存される。
(保存しなくても、後述の実行は可能。というか、書き捨てになるので保存しなくていい)
# This is a file for you to write an un-named mutation.
# Only one un-named mutation is allowed per file.
mutation {
movieMetadata_insert(
data: {id: "11111111222233334444555555555555", movieId: "11111111222233334444555555555555", description: "", rating: 0, releaseYear: 0}
)
}
「Read data」も同様にqueryが書かれたファイルが作られる
# This is a file for you to write an un-named queries.
# Only one un-named query is allowed per file.
query {
movieMetadatas{
movie {
title
imageUrl
genre
}
rating
releaseYear
description
}
}
この query
や mutation
の上にも拡張機能によってボタンが現れており、localかproductionに対して実行できる(嬉しい~~~)
クエリ定義
アプリケーションで使用するクエリを /dataconnect/connector/queries.gql
に定義する。
これもセットアップ時にサンプルコードがコメントアウトの状態で書いてあるのですぐ試せる。
query のコメントアウトを外すと CodeLensボタンが出るのでクリックするだけで実行できる
# @auth() directives control who can call each operation.
# Anyone should be able to list all movies, so the auth level is set to PUBLIC
query ListMovies @auth(level: PUBLIC) {
movies {
id
title
imageUrl
genre
}
}
@auth
ディレクティブってもしかして Firebase Authと連携できる感じか…?
ここではPUBLICにしているから全部取れる的な?
疑問
定義したqueryはコードからはどうやって参照する?
後述。
@auth
の levelってどう使う?
connector
とかの分け方の基準がよくわかってない
ディレクトリの -
.dataconnect
: Data Connect の機能によって自動生成されるファイル。.gitignore
で除外されている -
connector
: SDKとの接続のための設定、クエリ・ミューテーション定義など。 -
schema
: スキーマ定義。
ファイル命名の制約がどこまでかわからん
注: クエリとミューテーションは任意の .gql ファイルに配置できます。queries.gql や mutations.gql という名前にする必要はありません。
https://firebase.google.com/codelabs/firebase-dataconnect-web?hl=ja#1
つまり、サンプルコードでは例としてわかりやすくqueryとmutationで分けているけど、User, Movie, MovieMetadata みたいにエンティティごとにファイルを分けたり、使用するページごとで分けたりしてもいいわけだ
また、connectorのディレクトリを複数作ってもOK。
リレーションシップ
サンプルコードの MovieMetadata
には、 movie
というフィールドがあり、これが Movie
を参照している
type Movie @table {
# ...
}
type MovieMetadata @table {
movie: Movie! @unique # Movieを参照している
# movieId: UUID <- this is created by the above reference
rating: Float
releaseYear: Int
description: String
}
これにより、MovieをリストするときにMovieMetadataを引っ張って来れる(楽……)
movieMetadata_on_movie
のように、 <field>_on_<foreign_key_field>
の形式で自動生成されるらしい?
query ListMovies @auth(level: PUBLIC) {
movies {
id
title
imageUrl
genre
movieMetadata_on_movie {
rating
}
}
}
SDKを使う
VSCode拡張の「Add SDK to app」を実行で、SDKコードのサンプルができる。
src
ディレクトリを選択すると、以下のような構造でファイルができる
src(指定したディレクトリ)
└─dataconnect-generated
└─js
└─default-connector
│ index.cjs.js
│ index.d.ts
│ package.json
│
└─esm
index.esm.js
package.json
dataconnect/connector/connector.yaml
にこういう設定ができる
connectorId: default
generate:
javascriptSdk:
outputDir: ../../src/dataconnect-generated/js/default-connector
package: "@firebasegen/default-connector"
packageJsonDir: ../../src
(多分この設定を変えれば適当にディレクトリは変えられるはず)
src/dataconnect-generated/js/default-connector
というディレクトリが自動生成されたモジュールとなるので、これを参照することでクエリやミューテーションを呼び出すことができる。
スキーマやクエリ・ミューテーションの .gql
ファイルの変更を監視して、自動的に書き出しを行ってくれるっぽい(さすが 👏)
VSCode以外の環境では、watchオプションつきのコマンドで自動反映できるらしい。
クライアントコードの書き方
クエリ・ミューテーションをData Connectにデプロイ→クライアントから呼び出し、という流れ。
あくまで実行されるのはサーバーサイド。
よく考えたら、GraphQLサーバーはFirebase側で構築されるんだから、サーバーサイドのコードを一切書く必要ないのか…!
アプリケーションのデプロイ先は別にNodeサーバーじゃなくても静的に置いていいんだ
すげー
「自分のデータしか作成できない」「自分のデータしか読み取れない」みたいなセキュリティの部分は auth.uid
を参照することで担保するんだ。
Firestoreのrulesを書くことでクライアントからDBへの書き込み・読み取りのセキュリティを担保するのと近い感じだな
ローカルエミュレータを使う
エミュレータを使う場合は connectDataConnectEmulator
を使う
このドキュメントによれば listMoviesRef()
とか listMovies()
みたいにインスタンスわざわざ渡さなくても実行できるようなこと書いてあるけど、
やってみたら以下のようにdata connectのインスタンスを渡さないと、「initializeAppされていないぞエラー」が出てしまった。
const dataConnect = getDataConnect(app, connectorConfig);
const movies = await listMovies(dataConnect);
なにが違うんだろう 🤔
GraphQLでしか書けないから、複雑な処理をしたくなったときにSQLを書くことはできないのか。
ここはもうこのサービスの特性として割り切るしかないかな。
注: フィールド名にアンダースコア文字 _ は使用できません。Data Connect は、補足フィールド、暗黙的なクエリ、ミューテーションを生成するときにその文字を使用します。
https://firebase.google.com/docs/data-connect/schemas-queries-mutations?hl=ja
へー
デプロイ
VSCode拡張の「Deploy to production」でデプロイできる
(もちろんcliコマンドでもOK)
デプロイすると、コンソールから確認できる
コンソールからクエリ・ミューテーションの実行もできる
画面の下の方に実行結果の履歴が出てくる
感想
Firestoreのようなお手軽さでRDB&GraphQLが使えるの素敵すぎる…!
Firestore (NoSQL) はどんなドキュメントでも入れられてしまうがゆえ、型安全な運用がなかなか難しかった。
小規模なプロジェクトであろうと、型に守られて実行時エラーを避けたいので、本当に嬉しい。
早くGAしてくれ~~