ノーコード ラボ

NoCode 関連のツールの紹介、使い方などをやさしく説明しています。Chatbot の運用実験は終了しました。ご協力いただいたみなさん、ありがとうございました。

Bubble と Firebase Realtime Database を連携してみよう!

みなさん、こんにちは!今回は、以前の BuckendlessXano に続きまして、Bubble の外部 DB の候補の一つである Firebase Realtime Database との連携方法についてご紹介したいと思います。

Firebase のデータベース には「Cloud Firestore」と「Realtime Database」の2種類がありますが、今回は後者の Realtime Database との接続にフォーカスしています。なお、データベース自体の違いについては、以下リンクにあります Firebase のドキュメントで比較することができますので、ご参考いただければと思います。

firebase.google.com

また、Firebase との認証には無料プラグインである「Firebase Authentication Connector」を使用し、Realtime Database へのアクセスには API Connector で REST を使って接続していきたいと思います。

ただ、認証を行う Firebase Authentication Connector プラグインが対応しているアクションについては、ログインとログアウトの2つとなっています。その為、もし Firebase 側でユーザーの新規作成を行うサインアップ機能を実装したい場合は、ご自身でプラグインを作成するか、有料プラグインの導入を検討するなどといった別途対応が必要となりますので、ご留意いただければと思います。

本記事での連携においては、無料の範囲内で行いますので、どなたでもトライしていただきやすいのではないかと思います!では、早速始めていきましょう~!

👉 この記事はこんな人におすすめです

  • Bubble のデータベースとして外部サービスを検討している方
  • Bubble の API Connector や REST について学習中の方
  • Firebase Realtime Database と Bubble の連携について、ざっくり知りたい方

まずは、Firebase 側の設定から進めていきます。次に Bubble から Firebase での認証を行い、REST を使用してデータ接続していきます。Bubble側 では、ログイン処理と商品一覧の表示や登録が行える簡単なサンプルアプリを作成していきます。

1. Firebase 設定

Firebase の設定は以下リンクのコンソール画面から行います。Firebase には Google アカウントを使ってログインしていきますので、もしアカウントをお持ちでない場合はアカウント作成から進めるようにしてくださいね。

console.firebase.google.com

1.1. プロジェクト作成

Firebase プロジェクトの「+プロジェクトを追加」をクリックして、プロジェクト名を入力します。

Google アナリティクス(Google の分析ツール)を利用する場合は「有効」にしておきます。ここではデフォルトのまま「有効」に設定しました。

プロジェクトが作成できました!

1.2. Firebase Authentication の設定

次に Authentication です。Firebase Authentication とは、Firebase のユーザー認証機能サービスです。Firebase Authentication を使うことで、パスワードや電話番号、その他 Google や Facebook、Twitter などのアカウントを使用した認証を行うことができます。認証の種類は大きく分けて「FirebaseUI Auth」と「Firebase SDK Authentication」の2種類あります。今回は Bubble 側で「Firebase Authentication Connector」プラグインをインストールして認証を行う方法で実装していきますが、これは後者の Firebase SDK Authentication の認証方式を使用し、メールとパスワードでログインするプラグインになっています。

では、Authentication の設定をしていきましょう! Authentication メニューから「始める」をクリックして「Sign-in method」タブで「メール / パスワード」をクリックします。

「有効にする」をオンにして「保存」をクリックしてください。

1.2.1. テストユーザーの登録

冒頭でもお伝えした通り Firebase Authentication Connector プラグインは「Signin」と「Signout」には対応していますが、残念ながらユーザーを新規作成してくれる「Signup」には対応されていません。なので、今回のサンプルでは、ここで直接テストユーザーを登録していきます。「Users」タブを選択して「ユーザーを追加」から「メール」と「パスワード」を入力してください。

もしサインアップ機能も実装したい!という場合は、ご自身で SDK を導入することが前提となりますが、以下のドキュメントが参考になると思いますので、ぜひチャレンジしてみてください。

firebase.google.com

なお、ここで登録したメールとパスワードは Bubble 側でのログイン時にも使用しますので、忘れないようにメモしておいてくださいね。

1.3. Realtime Database の作成

では、次に Realtime Database を作成していきましょう。左側の「Realtime Database」メニューから「データベースを作成」をクリックします。

ロケーションを選択する画面が表示されますので、好きなロケーションを選択して次へをクリックします。なお、ロケーションは REST で使用するエンドポイントのURLに影響します。ここではデフォルトで表示される us-central1 を使用していますので、URL は DATABASE_NAME.firebaseio.com を使用します。もし別のロケーションを使用される場合は、 DATABASE_NAME.REGION.firebasedatabase.app となりますのでご注意ください。

DATABASE_NAME.firebaseio.com(us-central1 のデータベースの場合)

DATABASE_NAME.REGION.firebasedatabase.app(他のすべてのロケーションのデータベースの場合)

セキュリティルールを選択します。テストモードで開始すると、30日間限定でデータベースは公開設定となります。ここでは「ロックモードで開始」を選択します。

次に、Bubble からデータ接続ができるようにルールを編集しておきましょう。今回はサンプルということで、「認証ユーザーなら誰でも閲覧可能」とするルールに変更したいと思います。以下のコードをルールに適用して「公開」をクリックします。

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

Realtime Database の枠組みの完成です。次に、サンプルデータを登録しておきましょう。

右側の「︙」アイコンから JSON でデータをインポートすることができます。今回は以下のデータを登録しました。items ツリーには3つデータがあり、それぞれに idnameprice を持っています。

{"items": [
  {
    "id": "1",
    "name":"りんご",
    "price": "150"
  },
  {
    "id": "2",
    "name":"バナナ",
    "price": "200"
  },
  {
    "id": "3",
    "name":"いちご",
    "price": "300"
  }
]}

もし上記と同じデータをサンプルとしてインポートされる場合は、メモ帳などにコピーして、拡張子を「.json」としたファイルを作成してインポートを行ってください。

以上で、データベースの準備ができました!

1.3.1. NoSQL について

ここで少しだけ Realtime Database のデータモデルについて補足しておきたいと思います。Realtime Database は NoSQL という非リレーショナルデータベースです。本記事では NoSQL とは何か?という詳細については割愛させていただきますが、データは JSON オブジェクトとして保存されています。

データ構造を設計する際は、ユーザーがどのような角度からデータにアクセスするのか?という点を踏まえて、データを構造化する必要があります。データの構造化については、以下に Firebase のドキュメントがありますので、こちらも併せてご参考ください。

firebase.google.com

今回作成するサンプルアプリは、Firebase から REST で取得したデータを、そのまま単純に Bubble の Repeating group に表示させるようなデータ構造にしているのですが、これが正解という訳ではないので、NoSQL を導入される場合は、その特性が発揮されるようにデータ構造を検討してみてくださいね。

1.4. ウェブアプリ作成

では、続いて Bubble から接続ができるように Firebase でウェブアプリを作成していきます。「プロジェクトの概要」の横にある⚙️設定アイコンから「プロジェクトの設定」を開きます。

「マイアプリ」にある「</>」アイコンをクリックして、ニックネームを入力し「アプリを登録」をクリックします。ニックネームは後からでも簡単に変更可能です。

アプリが作成できたら接続に必要な設定値が取得できます。apiKey ~ measurementId まで8つの値を 後ほど Bubble 側の設定時に使用します。

以上で Firebase 側の準備が完了です!次は Bubble 側の設定を行います。

2. Bubble 設定

新規アプリを作成していただき、必要があれば、index ページを新レスポンシブエンジンに乗せ換えておいてください。ここでは、新レスポンシブエンジン版でページを作成していきます。

新レスポンシブエンジンって何?という方は、以下の記事でご紹介していますので、是非合わせてご参考くださいね。

blog.nocodelab.jp

2.1. プラグインのインストール

次に、Plugins タブから Firebase Authentication ConnectorAPI Connector をインストールしてください。

Firebase Authentication Connector には、先程 Firebase のアプリを作成した際に取得した8つの値を設定しておきます。

2.2. サンプルアプリ

では、ここからは Bubble で画面とワークフローを作成していきます。大まかな流れなどは以下の仕様で実装していきたいと思います。

  • index ページのログインポップアップで、Bubble と Firebase の両方に同時にログインさせる。User に関しては、Bubble の User Type も使用する。
  • ログインしたタイミングで Firebase Authentication Connector プラグイン経由で取得したトークンを Bubble の User Type に保存し、REST でのデータ接続の認証で使うようにする。
  • ログイン後は、items ページに遷移して、Realtime Database の items テーブルから取得した商品一覧を表示する。
  • データの作成、更新、削除は items ページから、 Realtime Database の items テーブルに対して行う。

2.2.1. 前準備

Page と Reusable element 準備

まずは前準備として、Bubble で以下の2ページを準備しておきます。ページの中身は空っぽで、新レスポンシブエンジンに乗せ換えたもので作成しておきます。

Page 名 詳細
index ログインページ
items 商品一覧ページ

次に、デフォルトで作成されている、以下の Reusable element を新レスポンシブエンジンに乗せ換えておいてください。

Reusable element 名 詳細
Signup / Login Popup サインアップやログインを行うことができるポップアップ
User Type

次にデータベースです。Bubble の User Type に「token」という名前のフィールドを追加しておきます。このフィールドは、認証で使用するトークンを保存する為のフィールドです。

テストユーザーの登録

Bubble 側でもテストユーザーを登録しておきたいと思います。メールアドレスとパスワードの両方を設定したユーザーを登録したいので、Signup / Login Popup の Reusable element を利用するなどして、Firebase 側でも登録したテストユーザーと同じユーザーを登録するようにしてください。

2.2.2. ログイン処理と Firebaseへの接続

では、index ページにログイン機能を実装していきます。出来上がりは Preview したら「Log in to My App」ポップアップが表示される状態です。

Signup / Login Popup を配置しただけの状態だと「Sign up」が初期表示となっていますので、「Log in to My App」が表示されるようにしておきましょう。

index の Workflow タブで「Do when Current User is logged out」イベントを作成(Do when condition is true を選択して、Only when を Current User is logged out に設定)します。Step1 で Signup / Login Popup の mode を「login」に設定し、Step2 で Popup を Show させます。これで、ログインされていないユーザーの場合は、Signup ではなく、Login のポップアップが初期表示されるようにできました。

逆にログインされているユーザーの場合は、items ページに遷移させるように設定しておきましょう。

次に「Log in to My App」ポップアップで「LOG IN」ボタンがクリックされた時に、Bubble と Firebase の両方にログインしていくように設定します。

Reusable element の Signup / Login Popup を開いて、Group Log in 内に Firebase Authentication Connector プラグインの element である「FirebaseContainer」を配置します。

次に Workflow タブで Custom event を作成します。ここでは「Get Token」という名前の Custom event を作成しました。作成した Get Token の Step1 に Make changes to thing... から Current User の token を、先ほど配置したFirebaseContainer の idToken で更新するように設定します。

次に「LOG IN」ボタンがクリックされた時の処理に、Firebase の認証を追加していきます。Step1 の Bubble のログイン処理の次に、Step2 で Firebase の Sign In を追加します。なお Sign In アクションは、Firebase Authentication Connector プラグインをインストールしたタイミングで、Plugins の中に表示されています。Step3 で先ほど作成した Custom event を Trigger します。

これで、Step1で Bubble の User Type を使って Bubble アプリにログインし、Step2 で Firebase Authentication を使って Firebase にログイン、Step3 で Firebase Authentication で取得した idToken を User Type の token フィールドに保存という処理の流れが設定できました。

なお、参考までに token の保存を Custom event にしているのは、Bubble の Workflow の実行順序を保証させる為で、Bubble 側でのログイン処理に掛かる時間が、Firebase からの idToken を取得するよりも早い場合に備えています。本記事の内容からは少し脱線してしまいますが、実行順序については過去にも取り上げていますので、よろしければ以下の記事もご参考ください。

blog.nocodelab.jp

次にログアウトボタンを作成しておきましょう。ログイン後は、items ページに遷移するので、items ページに「Log out」ボタンを配置します。

Workflow タブで、User Type に登録した token をクリアする Custom event を作成します。ここでは、名前を「Clear Token」としました。

次に「Log out」ボタンがクリックされたら、Step1 で Firebase Authentication Connector プラグインの Sign Out を、Step2 で先ほど作成した Clear Token を Trigger し、Step3 で Bubble から Log the user out、最後に Step4 で index に遷移するように設定します。なお、今回は特に設定していませんが、ログインしていないユーザーは items ページから締め出しなどが必要な場合は、適宜設定しておいていただければと思います。

では、index ページを Preview してログインしてみましょう。以下のように、token が更新され、items ページに遷移されればOKです。なお、前準備の際に、サインアップを利用してテストユーザーを登録した状態のままだと、ログイン状態になっているため、Preview すると items ページに遷移されるかと思います。その場合は、一旦ログアウトしてから進めるようにしてくださいね。

Firebase Authentication 画面でも、時間までは確認できませんが、ログイン日であれば確認することが可能です。

ログアウトすると、User Type の token がクリアされ、アプリからもログアウトして index ページに戻ります。

以上で、Firebase Authentication Connector プラグインを使用した認証が実装できました。

2.2.3. REST について

では、ここからは、REST を使ってデータ操作をしていきます。REST は API Connector を使用します。 REST では、GET や POST、PUT、PATCH、DELETE を使い分けることで、データの取り扱い方法を決定します。以下の表は、それぞれの役割を一覧にしたものです。

リクエスト 詳細
GET データのリストを取得します。
POST データのリストに追加します。POST リクエストでは Firebase クライアントにより一意のキーが生成されます。今回のサンプルでは Repeating group にデータを表示させたいので、unique id を発行せず登録を行うため使用しません。
PUT 定義されたパスに対してデータの書き込みや置換を行います。
PATCH データを置換することなく、定義済みのパスのキーの一部を更新します。
DELETE データの削除を行います。

まずは API Connector で API プロバイダーを作成します。Firebase への認証は、前項ですでに行っているので、Authentication はデフォルトの「None or self-handled」のままでOKです。API Name のみ設定しましょう。ここでは「firebase」としました。

データ取得

では、まずは GET を使って Firebase からデータを取得しましょう。エンドポイントは以下になります。

https://YOUR-APP-NAME.firebaseio.com/[db].json?auth=[key]

YOUR-APP-NAME は、適宜ご自身の Bubble アプリ名に置き換えてくださいね。[db] の部分はパラメータにしていますが、Firebase で作成したテーブル名となりますので、ここでは「items」を指定しています。また、[key] には、ログイン時に取得した token フィールドの値を入力しておきます。設定できたら Initialize してみましょう。

無事に取得できたら、items ページにデータを表示してみます。Repeating group を配置して、Type of content を API で設定した「GET Item Data」にして、Data source で GET Item Data の (path) key を「Current User's token」としたものを設定します。

Repeating group 内に Text を一つ配置して、GET Item Data から取得した name と price を表示させます。

Preview して取得したデータが表示されれば OK ですね!

データ新規作成

次にデータ登録を設定してきます。まずは、新商品が追加される API を作成していきます。データ登録では、ボタンをクリックしたタイミングで API を呼び出したいので、Use as を「Action」で作成していきましょう。PUT を使用してエンドポイントは以下に設定します。

https://YOUR-APP-NAME.firebaseio.com/[db]/[index].json?auth=[key]

[db][key] は、データ取得時の GET で使用したものと同じです。[index] は、Firebase 上で自動で採番される index 配列の値を指定する必要があります。今回のサンプルで登録するのは、4件目のデータとなるので、下図のように 0 から採番して「3」を指定します。

Body には items の中身となる以下を設定します。Body parameters に登録したい値をセットして Initialize します。

  {
    "id": "<id>",
    "name":"<name>",
    "price": "<price>"
  }

ここでは、API の Call 名を「PUT Item Data 」としました。

Initialize に成功したら、画面から商品の新規登録ができるように実装していきます。今回は「アイテム作成」ボタンをクリックしたら、ポップアップを表示させて登録できるようにしていきたいと思います。

Group を使って「アイテム作成」ボタンを作成します。

ポップアップには、Body parameters で登録する id、name、price が指定できるインプットと、「登録する」ボタンを配置しておきます。

では、次に Workflow タブで処理を設定してきます。「アイテム作成」がクリックされたら、新規作成のポップアップを Show します。

次に、ポップアップで「登録する」ボタンがクリックされたら、Step1 で API の PUT Item Data を呼び出して、index に 現在取得している items のデータ数を、key には Current user の token、id と name、price にはインプットの値を登録するように設定します。Step2 ではデータを再取得するのに Refresh the page させておきます。

では、Preview して登録してみましょう。

データ更新

次に、商品データを更新できるようにしますが、更新は PUT と PATCH の2つの方法で実装ができます。両者の違いは、PUT は置換によって更新し、PATCH は定義済みのキーを編集することで更新します。

PUT で更新

PUT でデータ更新を行う場合は、先程の PUT Item Data を流用することで実装できます。更新の場合は (path) index に firebase 側の index 配列の値(下図の赤枠部分の数値)をセットすることで、指定したデータの値を更新します。ただし、firebase 側の index 配列の値は明示的に取得することが難しいようなので、ここでは Repeating group で取得した際の Current cell's index を利用して更新することとします。

更新ボタンとなる「編集」アイコンを配置して、「データ修正」ポップアップを作成します。

ポップアップには、選択した items データと、REST の URL となる index を保持することができる Custom state を作成しておきます。名前はそれぞれ「item data」と「Current cell's index」としました。

Workflow タブでは「編集」アイコンがクリックされたら、作成した Custom state に値をセットしてから、ポップアップが Show されるように設定します。

「データ修正」ポップアップの「修正する」ボタンがクリックされたら Step1 で PUT Item Data を呼び出し、Step2 で Refresh the page しておきます。なお、PUT Item Data の (path) index で、Current cell's index から -1 した値をセットしているのは、Firebase 側では index 配列 が 0 から採番されているためです。

では、Preview してデータを更新してみましょう。ここでは、4件目のデータである「メロン」の金額を「500」から「800」に更新しました。

なお、PUT でデータを更新する場合は「置換」となることに注意してください。更新しない値がある場合でも Body parameters には含める必要があります。もし、データを置換することなく、定義済みのパスの値の一部を更新したい場合は、次の PATCH を使うようにします。

PATCHで更新

次に、PATCH を使って更新していきます。PATCH は商品の一括更新などにも使える便利な機能ですが、Bubble 側では、Body で必要な JSON の作成において工夫が必要になります。今回は PATCH の実装については、画面などの作成は割愛させていただき、API Connector の Initialize を使用しての接続確認だけを行いますので、ご了承ください。

エンドポイントは、GET の時の同じものになります。

https://YOUR-APP-NAME.firebaseio.com/[db].json?auth=[key]

Body には以下のフォーマットで指定します。

  {
    "index/key": "value"
  }

今回のサンプルでは、

{
  "1/name": "banana ",
  "1/price": "100",
  "2/name": "strawberry"
}

と指定することで、「ばなな」の name を「banana」、price を「100」に、「いちご」の name を「strawberry」に更新します。Initialize してデータが更新されるか確認してみましょう。

このように、PATCH では指定したパスにある、キーの一部を更新することができます。

データ削除

では、最後にデータ削除を実装していきます。画面については、以下のように「削除」アイコンを配置して、削除 API を呼び出すこととします。もしくは、データ更新の時と同じように、ポップアップを1枚挟んでも良いですね。

では 削除 API を設定します。エンドポイントは、PUT と同じものを使用し、削除時はレスポンスを受け取らないので、Data type は「Empty」にしておきます。

https://YOUR-APP-NAME.firebaseio.com/[db]/[index].json?auth=[key]

Initialize を実行して削除してみましょう。

Firebase側では Initialize で実行した index が 3 の商品(メロン)が問題なく削除されました。

続いて Bubble 側ですが、こちらは留意しておく点があります。Bubble においては以下の図のようにデータは空欄として扱われてしまいます。Bubble 側ではデータが empty と判断されているため、このような結果になるようですね。

削除データは普通表示させたくないデータになると思いますので、実際には空白データを表示させないようにしておくと思いますが、その際注意しておくこととしては、 :filter で絞り込みを行うと、Repeating group の Current cell's index がズレるといったことが考えられます。その場合、今回のサンプルのデータ更新方法だと問題が発生してしまうため、そういった場合はデザインで工夫するなど、別の対応が必要になってくるかもしれません。

また、上記のように Bubble 側でデータが empty として取り扱われる際、空白のデータ件数が連続する(確認した限りでは5件以上 empty が続く)と Repeating group に上手く表示されないといったこともありました。なので、NoSQL のメリットを生かすためには、データ構造を含めた検討や、直接 API で取得したデータを Repeating group の Data source にセットしないようなやり方の方がベターかもしれません。

3. まとめ

いかがでしたか?今回は、Firebase と Bubble の連携方法についてご紹介しました。

また、Bubble で外部 DB を使用する場合、ユーザーは Bubble に持たせるか?それとも外部か?といった議論もあると思いますが、今回は、ユーザーに関しては Bubble にも持たせて、それ以外の DB を外部で管理といったシナリオを想定して作成してみました。

外部 DB の使用は、費用などの面で効果的である一方、多少のデメリットも存在します。例えば、今回のような接続方法では Realtime Database なのに実際はデータを再読み込みする必要があり、リアルアイムにならないといったことや、操作したいテーブルの数や機能に合わせて API Connector の設定も肥大化するなどといった点です。

外部 DB を検討する際は、何を優先していく必要があるのか?開発するサービスの規模やデータモデル、仕様なども含めて比較してみてくださいね。

それでは、ここまでお読みいただき ありがとうございました!では、次回もどうぞお楽しみに~!

4. 関連記事

blog.nocodelab.jp

blog.nocodelab.jp