RDB初心者がFirebase Data Connectを触ってみた！ ①データ挿入〜取得まで

# 概要
今回 **Firebase Data Connect** と呼ばれるFirebaseでPostgreSQL(RDBS)が使えるようになる新機能に、RDBSに触れてこなった初心者がハンズオンでチャレンジしてみました！NoSQLには慣れている私ですが、どのようにこの新しい機能を活用できるのかを試してみたのでその体験を共有したいと思います

# 前提
- 自社で社内業務Webアプリを作るフロントエンドエンジニアをやっています
- 活動してるプロジェクトのDBはFirestore（NoSQL）を使用しています
- RDBはRails+MySQLでちょこっと触ったぐらい　GraphQLは触ってことがない


# Firebase Data Connectって？
https://firebase.google.com/products/data-connect?hl=ja



わかりやすく説明している公式の動画もあります（日本語訳はないので自動翻訳で見た）
![スクリーンショット 2024-05-24 14.35.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/b388404d-bdea-8f2a-fbad-3feba8eb007c.png
)
https://www.youtube.com/watch?v=7OdVatEI85o


GPTに要約をお願いすると
> Firebase Data Connectは、Cloud SQL for PostgreSQLを使用して、安全でスケーラブルなモバイル、ウェブ、およびAIアプリケーションを迅速に構築するためのツールと機能を提供します。デフォルトで安全性が確保され、パフォーマンス監視やローカル開発ツールも充実しています

つまりGoogle Cloudが提供するフルマネージドのPostgreSQLサービスですね　
ホスティングやらセットアップやらのインフラ周りを気にしなくていいので初心者の自分にはありがたいです

# 早速使ってみよう
現在は限定公開プレビューのみなので、早期アクセスに申し込んだ後送られてくるメールの中にあるブラウザ版IDE（IDX）を使うとすぐにハンズオンが可能です
既存のプロジェクトにデプロイしたり試したりするには許可を待つ必要があります

既に やってみる と書いてある公式ドキュメントを見つけたので、これ待たなくても既存のFirebaseプロジェクトを使ってローカルとかからでも使えるのかな？と勘違いし3時間くらい試した結果できなかったのでそこら辺も記載しておきます

## 早期アクセスを申し込む
![スクリーンショット 2024-05-24 14.34.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/d69dc6aa-5c94-1371-dcf8-a99b885c6533.png)

個人情報やらを登録し、待ってるとメールが返ってくるのでClick here(Project IDXリンク)をクリックする



![スクリーンショット 2024-05-21 17.11.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/3c65706b-c07c-25d0-6d30-20e5c928ba26.png)


IDXでプロジェクトの名前を好きなのに設定してスタート

本記事ではデータ挿入からクエリでデータを取得するまでをやってみようと思います

## 流れ
 - 1 左バーメニューからFirebaseを選択する
 - 2 Start Emulator ボタンを押す
 - 3 dataconnectフォルダにあるgqlからスクリプトを起動
 - 4 connectorフォルダからクエリを動かす
 - 5 スキーマからもやってみる

### 1.左バーメニューからFirebaseを選択する
このアイコンをクリックするだけ
![スクリーンショット 2024-05-27 9.01.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/16783de0-f063-c8d8-94aa-c0dca26286f5.png)





### 2. Start Emulator ボタンを押す
これを押すとエミュレーターが起動する　成功すると右下に成功したという通知が来る
![スクリーンショット 2024-05-24 14.59.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/be7e7468-5949-60f6-bc55-b29ae9465a53.png)

![スクリーンショット 2024-05-27 10.46.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/1ba2e66f-314b-b38a-79a7-ecc559fa0551.png)

### 3. dataconnectフォルダにあるgqlからスクリプトを起動
![スクリーンショット 2024-05-27 11.08.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/ac1e2561-8a72-683f-2dbf-07c3776f22a4.png)

試しにUser_insert.gqlを開くとテストデータを用意されてました
クエリが既に書かれているので早速Run（local）してみます　すると...

![スクリーンショット 2024-05-27 11.13.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/d3d2c79f-bf1a-e1d1-8841-b29193c95020.png)

ターミナルがあった場所にDATA CONNECT EXECUTIONタブが出てきました
HISTORYを見る限りどうやらデータ挿入に成功したようです！


### 4. connectorフォルダからクエリを動かす
![スクリーンショット 2024-05-27 11.19.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/64e08c83-1493-a62e-26ba-dd6a6447c054.png)

次に先ほど入れたUserデータをクエリで取り出してみます
connectorフォルダにあるqueries.gqlファイルを開き、一番上のListUsersを確認します
私はGraphQLに触れるのが初めてなのですが、GraphQLでは 

```
email: address # 右がフィールドデータで左の名前になる
```
こんな風にしてエイリアスをつけるんですね　試しにちょっと変えてみます

![スクリーンショット 2024-05-27 11.24.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/656dfd9c-ee46-8b8e-7103-3288a3c5391e.png)

Run(local)を押してDATA CONNECT EXECUTIONタブを確認すると...

![スクリーンショット 2024-05-27 11.25.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/7de5d7ed-348d-27e6-5d5c-d78dd47d3d56.png)

無事取得できてますね！

### 5. スキーマからもやってみる
schema.gqlがあったので自分でも一つ作ってみようと思います
```aa
type Packages @table(key: "uid") {
  uid: String!
  name: String!
  weight: Float!
  shippingDate: String!
  destinationAddress: String!
  status: String!
}
```

スキーマタイプを作るとUIにAdd dataとRead dataが出てきます　Add dataを押すと自動でgqlファイルを生成してミューテーションのクエリを作ってくれるようです
![スクリーンショット 2024-05-27 11.35.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/be12f758-6940-96f2-e4ad-c41b9bca2a66.png)

いい感じに作って

```graphql
mutation {
	packages_insert(data: {
		name: "refrigerator" # String
		weight: 5 # Float
		shippingDate: "2024-05-27" # String
		destinationAddress: "123 Ocean Drive, Sea City" # String
		status: "InTransit" # String
		uid: "refrigerator_package_0" # String
	})
}
```
Run!

![スクリーンショット 2024-05-27 11.39.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/5f2c324b-ef2d-2d51-df90-c17c559da321.png)

スキーマファイルに戻って今度はRead dataを使ってみましょう
![スクリーンショット 2024-05-27 11.40.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/4e7ae0c8-344e-f0a9-2143-6c65f4cc26c7.png)

![スクリーンショット 2024-05-27 11.40.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/3d61f9cd-fca9-e0b4-6fa3-301f68046158.png)

こちらも自動で作られてますね　Run！

![スクリーンショット 2024-05-27 11.42.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/80221ec3-1a10-a57e-7d79-609f9597de44.png)

取れてますね！（１個目は名前入れるの忘れて失敗したやつ）

## クライアントSDKコードとクライアントアプリからデータをクエリする
本当は上記の操作をJavaScriptで行うまで進めたかったのですが、自身のプロジェクトを初期化して使う段階でdataconnectを使う権限がなくできませんでした（ここがメインで凄い所なのに...残念）

やり方だけ載せておくと、Firebaseを初期化した後、getDataConnectに接続してFirestoreみたいに予め作っておいたクエリに使ってデータを取得するといった流れだそうです
```js
const { initializeApp } = require("firebase/app");
const {
  connectDataConnectEmulator,
  getDataConnect,
} = require("firebase/data-connect");
const { listUsers, connectorConfig } = require("@email-app/email");

// TODO: Replace the following with your app's Firebase project configuration
const firebaseConfig = {
  //...
};

initializeApp(firebaseConfig);

const connectorConfig = {
  connector: 'email',
  service: 'local',
  location: 'us-central1'
};

connectDataConnectEmulator(
  getDataConnect(connectorConfig),
  "localhost", //ドメイン
  9399 //ポート
);
```

私のプロジェクトで許可が出たらやってみる予定です！

## 感想
実際にまだWebアプリからデータを抽出したわけではないので不完全ではありますが、人生初のRDBとのことで非常に楽しみです
操作自体も簡単でサクサク実装できそうなのはFirebaseの強みが出ていてありがたい限りです
Firebaseを選んだ以上RDBを触るのは今後別プロジェクトかなーと思っていたのですがまさかのアップデートで期待感が高まっているので、今後も進展あり次第記事にしていきたい次第です！


## ローカルで試したやつ ※気になる人だけ

自分で試したけどどうしてもできなかったので断念　もしかしたらできる人がいるかもしれないので詰まった部分を記載


まずドキュメントに書かれているようにVS Codeに拡張機能をインストール

![スクリーンショット 2024-05-21 15.07.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/7a83ad56-42a5-f58d-5508-2b1eb999ef37.png)

![スクリーンショット 2024-05-27 14.21.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/a22bd617-0dc4-f53a-885e-e9aaaa4fbb6b.png)



その後firebaseコマンドでdataconnectで許可
```
firebase experiments:enable dataconnect
```

しようとしたら最新バージョンじゃなきゃダメとのことでfirebase-toolsを再インストール
```markdown
ryoharada@Harada-Ryo FirebaseDataConnect % firebase experiments:enable dataconnect

Error: Cannot find experiment dataconnect

   ╭───────────────────────────────────────────────────────────────────╮
   │                                                                   │
   │                 Update available 13.7.3 → 13.9.0                  │
   │          To update to the latest version using npm, run           │
   │                   npm install -g firebase-tools                   │
   │   For other CLI management options, visit the CLI documentation   │
   │                                                                   │
   │                                                                   │
   │                                                                   │
   ╰───────────────────────────────────────────────────────────────────╯
```

インストールしてもう一度　成功

```markdown
ryoharada@Harada-Ryo FirebaseDataConnect % firebase experiments:enable dataconnect    
Enabled experiment dataconnect
```

次にfirebase initしData Connectで新プロジェクトを作ろうとすると・・・

```a

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

You're about to initialize a Firebase project in this directory:

  /Users/ryoharada/FirebaseDataConnect

? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your 
choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
 ◯ Remote Config: Configure a template file for Remote Config
 ◯ Extensions: Set up an empty Extensions manifest
 ◯ Genkit: Setup a new Genkit project with Firebase
❯◯ Data Connect: Set up a Firebase Data Connect service.
 ◯ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
 ◯ Firestore: Configure security rules and indexes files for Firestore
 ◯ Functions: Configure a Cloud Functions directory and its files
```


```aa
Error: HTTP Error: 403, Permission denied to get service [firebasedataconnect.googleapis.com]
Help Token: ~
```

firebasedataconnect.googleapis.comのAPIがないよ！だからできないよ！と言われる
GCPのAPIとサービスで探したものの見当たらず・・・追加はできなかった
ちなみに Dataconnect を選択してプロジェクトなしで作成を行うと成功し、以下の設定を進めると無事initは成功する

```abap
? Please select an option: Don't set up a default project

=== Dataconnect Setup
? What ID would you like to use for this service? dev-connect
? What ID would you like to use for your connector? my-connector
? What ID would you like to use for your new CloudSQL instance? dataconnect-test
? What location would you use for this instance? asia-southeast1
? What ID would you like to use for your new database in dataconnect-test? dataconnect
? What is the connection string of the local Postgres instance you would like to use with the Data Connect emulator? 
postgresql://localhost:5432?sslmode=disable
✔  Wrote dataconnect/dataconnect.yaml
✔  Wrote dataconnect/connector/connector.yaml
✔  Wrote dataconnect/schema/schema.gql
✔  Wrote dataconnect/connector/queries.gql
✔  Wrote dataconnect/connector/mutations.gql

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...
i  Writing gitignore file to .gitignore...

✔  Firebase initialization complete!


```

VS codeにもそれっぽいプラグインが出てくる

![スクリーンショット 2024-05-21 15.49.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/144b2d61-d8b8-1c16-32ae-0fa1fe3ba356.png)

![スクリーンショット 2024-05-21 15.52.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986335/ae317238-e56b-c4f3-2320-7c3462e7794c.png)

しかし実際にemulatorの起動やデプロイをしようとすると・・・

```aa
Error: HTTP Error: 403, Permission denied to get service [firebasedataconnect.googleapis.com]
Help Token: ~
```

APIがないとダメなのは変わらず、ここで調べても情報がなかった為断念
恐らく早期アクセスに申し込んだ後許可が降りる方式なのだろうが１週間ほど経ったがメールは来ず...
メールが気次第再チャレンジする予定です！