2018-12-17に更新

Firebase Realtime DBの実戦投入を振り返る - 採用方針やセキュリティで気をつけたことなど

読了目安:10分

Crieit Advent Calendar 2018」の記事です。2018年は、業務で「Firebase Realtime Database」を使った1年でした。

https://firebase.google.com/docs/database/?hl=ja

Realtime Databaseは、 数ミリ秒で各クライアントへデータを同期 します。はじめて使ったときは、とても感動しました。開発したシステムでは、リアルタイムのデータ表示が必要な、特定機能に限定してRealtime Databaseを投入しています。

色々と工夫した点がありますので、今回はその辺りの知見を共有します。

RDB(Relational Database)との併用

「Firebase Realtime Database」は、データベースとして単体で使うわけではなく、 PostgreSQLと併用して運用 しています。

それには、いくつかの理由があります。

  1. はじめて使うので、ミニマムにプロジェクトで採用し、様子を見ることにした
  2. データ容量や転送量に連動する従量課金のため、最低限のリアルタイム表示に必要なデータだけ置くことにした
  3. Realtime Databaseは、柔軟なクエリ発行が苦手です。管理画面をはじめとする、細かな検索条件が発生するシーンには不向きでした

棲み分けとしては、リアルタイム表示が必要なデータをRealtime Databaseに投入し、それ以外はRDB(PostgreSQL)に保存しています。

また、Firebase Console上の誤操作で、データを上書きしたり消失できてしまう可能性があります。そこで、復旧スクリプトも用意しました。

具体的には、PostgreSQLにあるマスターデータを元にして、API経由でデータを再セットするスクリプトです。ただ、一度も出番はなかったです。

セキュアなデータはRDB(PostgreSQL)に置く

また、PostgreSQLを併用しているもうひとつの理由に、セキュアなデータを置きたくなかった点があります。

後述するセキュリティルールを工夫すれば対策も可能ですが、保険をかけて、セキュアなデータはサーバーサイドのRDBに暗号化して保存してします。

セキュリティルールの調整で、書き込みを拒否する

セキュリティルールは、基本的に以下の設定で運用しています。私の場合、 書き込みは許可せず運用する ことにしました。

また、リアルタイムのデータ表示に必要な特定のテーブルに絞って、読み込みを開放しています。

{
  "rules": {
    ".read": false,
    ".write": false,

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

書き込みを拒否した理由は、主に以下の3点です。

  1. PostgreSQLのマスターデータにも反映したかったので、書き込みはサーバーサイドで処理したかった
  2. フロントエンドJSから直接データを書き込ませないことで、安全性を高めたかった
  3. 認証は自前でやっており、Firebase Authenticationで認証していない。そのため、細かな書き込み権限の制御が難しかった

なお、書き込みを許可しなかったとしても、 Admin用のライブラリを使えば書き込みは可能 です。PHPには公式のAdmin SDKがなかったので、OSSを利用しました。

GitHub - kreait/firebase-php: Interact with Google Firebase from your PHP application

読み込み側の権限は「auth != null」にしています。念のため、Firebase Authenticationの匿名認証を挟んで運用している形です。

20181216200759.png

GCP(Google Cloud Platform)と連動している点に注意

Firebaseのプロジェクトを開設すると、 GCP(Google Cloud Platform)のConsoleでもアクセスできる ようになります。この点はかなり重要です。

私が技術書典4で頒布した「Realtime Database x React本」でも、注意事項を書いてます。抜粋して掲載します。

「APIとサービス」の認証情報を確認すると、Firebaseが自動で作成したキーがあることが分かります。そして、APIキーにおける警告マークは、APIキーが無制限であることを示しています。実運用で使用される場合は、設定は必須であると言えます。開発段階でも、可能な限り制限を設定することが望ましいでしょう。

WEBサービスであればリファラで、モバイルアプリであればバンドルIDなどでAPIキーを制限するのが基本形です。これを設定しておかないと、 Firebase用のアクセスAPIキーが無制限状態で運用 されてしまいます。

少し内容が古くなってしまいましたが、技術書典4で頒布した本にもFirebaseの概要を書いてます。無料でダウンロードできます。

Firebase Realtime Database と React.js で始めるリアルタイム アプリケーション入門 - - BOOTH

Realtime Databaseの実装は、メルカリを参考にするのがオススメ!

私がプロジェクトで採用した構成は、 「PHPカンファレンス2017のメルカリチャンネル」 をベースにしています。

PHPカンファレンス2017でFirebase Realtime Databaseについて登壇してきました #phpcon2017 - Mercari Engineering Blog

会場でメルカリの@sota1235さんに質問して、 「半年ほど運用しているが、一度もダウンしたことはない」 という返答をもらったのが、採用の決め手になりました。

メルカリチャンネルにおけるRealtime Databaseの知見は、他の記事でも共有されています。ぜひ参考にしましょう!

メルカリチャンネルにおけるFirebaseの利用例 - Mercari Engineering Blog

Cloud Firestoreとの関係性

Realtime Databaseの対抗馬として、Cloud Firestoreがあります。

Cloud Firestore  |  Firebase

個人的には、以下のような印象を持っています。

  1. Cloud Firestoreは、まだベータ版である
  2. クエリの柔軟性は、Cloud Firestoreのほうが高い

Cloud Firestoreの特徴である 「クエリ処理の機能性、効率性、柔軟性」 は、とても魅力的です。

さいごに

リアルタイムのデータ表示が必要な、特定機能に限定してRealtime Databaseを投入しました。感触はとても良いです。

また、オフライン対応があるのも魅力的です。もしデータ同期に失敗しても、クライアントがオンラインになったら、自動的に同期を再開します。これを自前のWebSocketで実装するとしたら、相応の苦労が必要なことは間違いありません。

巨人の肩の上にのることのメリットを、改めて実感した1年でした。

Originally published at www.konosumi.net

このすみ

エンジニア。ブログで、映画・ゲーム・読書の感想を書いたり、技術系の知見を発信しています。 技術書典5で「エンジニアアンチパターン」と「PHP中級者を目指す 〜言語を使いこなすための本〜」という本を出しました。

Crieitはβバージョンで開発中です。進捗は公式Twitterアカウントをフォローして確認してください。 興味がある方は是非記事の投稿もお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

関連記事

コメント