Firebaseでバックエンドエンジニア不在のアプリ開発 クックパッドが体感した、メリットと課題
Firebaseが依然として注目を集めていますが、早々に導入したクックパッドの「Firebase使用例」を紹介します!クックパッドの新アプリ開発で導入され、アプリやWebサイトのインフラ部分を任せられるほか、リアルタイムでデータを同期できるCloud Firestore、ログイン認証システムを手軽に実装できるFirebase Authenticationなど、さまざまな機能を活用しています。活用してわかった、Firebaseのいいところ、そして気をつけるべきポイントとは?
「Firebaseならバックエンドエンジニアを必要としない開発ができる」
そんな話を聞いたことがある人もいるかもしれません。「Firebase」は2011年にFirebase社がサービスを開始し、2014年にGoogleが買収したMBaaS(mobile backend as a Service)で、開発者が作成したアプリやWebサイトのインフラ部分を任せることができます。
Firebaseは、リアルタイムでデータを同期できるCloud Firestoreや、プッシュ通知を簡単に実装できるFirebase Cloud Messaging、ユーザーがログインする際の認証システムを手軽に実装できるFirebase Authenticationなどのほか、他にも多岐にわたる機能が用意されています。加えて、それら全てがブラウザから簡単に操作できるのも魅力の一つです。
ただ、Firebaseは一部の機能がまだベータ版であり、世界的に見ても開発事例が少なく、日本でも先人となる企業は少ないのが現状です。
そんな中、クックパッドが2018年6月、Firebaseで開発した料理が楽しくなるマルシェアプリ「Komerco(コメルコ)」をリリースしました。Komercoは、データも含めバックエンドでFirebaseを活用しており、バックエンドエンジニアが一人もいない状態で開発しています。
今回はKomercoの開発に携わった3名のエンジニアに、実際に運用をしているからこそ分かったFirebaseのメリットとデメリットを教えてもらいました。
- 岸本 卓(きしもと・すぐる/@sgr_ksmt_dev)(写真左)
- 2017年クックパッドに入社。現在Komerco事業部にて「Komerco」の開発に携わっている。iOSアプリ開発は2011年から、Firebaseは実務及び個人開発で2016年ごろから取り組んでいる。
- 星川健介(ほしかわ・けんすけ/@star__hoshi)(写真中)
- 2017年クックパッドに入社。現在Komerco事業部にて iOS アプリとサーバサイドの開発を行っている。個人開発が好きで、今まで20本以上のアプリを個人でリリースしている。
- 三浦和也(みうら・かずや/@__miup)(写真右)
- 2017年に新卒でクックパッドへ入社。複数の新規事業開発を経た後 Komerco 事業部で「 Komerco」の開発を行っている。iOS アプリ開発は学生時代から5年ほどやっており Firebase は入社してから触り始めた。
バックエンドエンジニアが誰もいない開発 未熟な技術ゆえ最初は不安も
―― Komercoは「料理が楽しくなる料理道具や雑貨」をクリエイターから直接購入できるCtoCアプリとのことですが、それぞれどのような開発を担当をされているのでしょうか?
岸本:僕はユーザのログイン認証周りや、アカウント設定関連を主に担当しています。画面の設計やiOSアプリの開発に重きを置き、アプリ側を広く見ている感じです。
星川:iOS開発をしつつ、サーバサイドを多く担当しています。クレジットカード決済や口座間の送金といった課金関連、スタッフが使用する管理画面の作成など、サービスの裏側も開発しています。
三浦:僕は全文検索の機能などを担当しました。Firebaseは検索機能が弱いため、Algoliaという外部の検索機能サービスを利用していて、主にそのあたりの連携・整備ですね。Algoliaとの連携部分ではCloud Functions for Firebaseも使っており、そのコードを書いています。
岸本:僕らは3人ともiOSエンジニアで、Komercoの開発チームにはバックエンドのエンジニアが一人もいません。iOSの開発をしつつ、Firebaseでバックエンドの管理もしています。
―― 「Firebaseでの開発はバックエンドエンジニアを必要としない」とは聞いていましたが、実例を聞くのは初めてです。チームメンバーはもともと、Firebaseでの開発経験が豊富だったのでしょうか。
岸本:僕は、前職で少しFirebaseを使っていたのと、個人アプリの開発でも利用していましたが、他のメンバーはほぼ未体験でしたね。星川は2017年10月ごろにチームに参加したときから、新卒で入社した三浦もKomercoチームにジョインした5月から使い始めました。
星川:「Firebaseで行く」と聞いたときは、正直「まじでやるのか……」と思いました(笑)Komercoはお金が絡むCtoCのECサービスなので、まだまだFirebaseのベストプラクティスが確立されてない状態で触るのは不安でしたね。「開発が速くなる」という話も前例がほぼないので、「本当なのか?」と疑心暗鬼でした。
豊富な機能が少数精鋭の開発をサポート
――不安な気持ちの中でスタートした開発は、実際に「速かった」のでしょうか?
星川:「iOSエンジニアが全ての開発を担当できる」という点では速いと思いました。例えば購入画面を作成する場合、画面を作って、購入の機能を作って、動かして確認して……と全部一人でできるので、サーバサイドエンジニアとやりとりしなくて済みます。あとはFirebase Authenticationを使うと認証機能がすぐに作れるのは楽ですね。
岸本:バックエンドのことを考えないで済むので、単純にやるべき作業に集中できるというメリットもあります。データやセキュリティ設定もFirebaseの管理画面から操作できるので、ノウハウさえあれば素早く開発を進められると思います。
三浦:僕も、インフラについて考えなくていいといいうのは利点だと思います。サービスの成長を考えると「どうやって負荷分散するか?」という課題が出てくると思うのですが、FirebaseではCloud Functionsを使うとオートスケールしてくれますし。
他のサービスのトリガーでコードを自動実行することができる。例えばデータベースに変更があったときや、ユーザアカウントの作成時などをトリガーとして、コードを実行することができる。
星川:僕らみたいな“アプリ開発の人”でも、Firebaseであれば「バックエンドをちょっと見てみるか」という気持ちで開発できるのは、やっぱり大きなメリットですね。また、KomercoではReactでWebの管理画面やティザー画面を作っていて、デザイナーがコードを書いているので、フロントエンジニアもいないんです。
―― iOSエンジニアとデザイナーで全ての開発ができている、というわけですね。すごい……。ところで、Firebaseではさまざまな機能がありますが、Komercoでは何を利用していますか?
岸本:まず、データは全てCloud Firestoreに持たせています。プッシュ通知もFirebase Cloud Messagingを利用するとかなり簡単に実装できますね。他にもA/BテストができるFirebase Remote Config、先ほども触れたイベントを受け取って処理ができるCloud Functionsなどを利用しています。
三浦:もともと、データベースはFirebase Realtime Databaseを使用していましたが、2017年10月にCloud Firestoreが公開されてからは、Firebase Realtime Databaseを補完するようなさまざまな機能が追加されて、簡単なクエリは書けるようになりましたね。
星川:あとは、Firebase AnalyticsとFirebase Crash Reporting機能を連携すると、Firebaseだけでクラッシュ分析ができるので便利ですよ1。
Firebaseは「データベース設計」「マイグレーション」に課題アリ
―― Firebaseを用いた開発を進める中で、ぶつかった「壁」はありますか?
星川:データベース設計ですね。MySQLなどのRDBでは、正規化をするのが「普通」だと思うんですが、Cloud Firestoreは正規化が「正解」じゃないケースが多いんです。例えば、普通のSQLだと正規化してもJOINして一発でデータが取得できますが、Cloud Firestoreはネストした分だけフェッチしないといけないので、データアクセスがかなり増えてしまうんです。RDBを使っている人ほど、NoSQLなFirebaseでのデータベース設計に一度は悩むと思います。
―― RDBを触っている人からすると、正規化しないのは違和感がありそうですね。
星川:めちゃくちゃ気持ち悪いですよ(笑)正規化しない場合は、関連するテーブルで同じデータを重複して持つ必要があって。例えばKomercoでは「購入後の金額」は変更されないデータでアクセスも多いため、複数のテーブルに持たせているんですが、僕はずっとRDBを使ってきたので、この設計に慣れるまでにかなり時間がかかりました。「同じデータを複数のテーブルに持たせる」というのが、分かっていても腑に落ちなくて……。
三浦:逆に僕は、RDBをめちゃくちゃ使っていたわけではないので、気持ち悪いみたいな感覚は少なかったですね。Cloud Firestoreを触っていて「こっちの実装の方がデータを取りにいきやすいな」と、なんとなくの感覚が身に付くようになりました。
――なるほど、先入観がない方が壁は低そうですね。いずれにせよデータベース設計にはかなり苦労しそうな印象を受けました。
岸本:NoSQLはスキーマレスでデータの形式が自由なだけに、事前の設計はかなり重要です。フィールドに書き込んだデータの型が分からなかったりするので。
MySQLだと「フィールドには文字列しか入らない」というルールが見た目で分かるけど、Cloud Firestoreでは分からないので、開発者同士で認識を合わせないといけません。型がないと文字列のカラムに数字が入ってるということがあり得るので、チーム内でのドキュメント作りと共有が重要になってきます。
星川:Cloud Firestoreで型の設定ができない分、サーバサイドではTypeScriptでデータベースのテーブルと同じクラスを定義するようにして、型チェックをしています。Swiftでも同様にチェックをして、安全性を担保できるようにしていますね。
―― 実際に開発をしてみないと分からない意見と、解決策で納得感があります。ほかに、気を付けるべきことはありますか?
岸本:普通のアプリケーションは、APIのレスポンスで必要な値だけを返すことができますが、Cloud Firestoreだとデータのカラムが全て返ってしまうんです。そのためユーザーテーブルを設計するときは、パスワードなどの非公開データは取得されないようテーブルを別に分ける必要があります。NoSQLの設計が難しい上に、セキュリティのことも考えないといけません。
―― それは大変ですね。個人的には、マイグレーションをどうしているのか気になりました。
星川:マイグレーションはかなり難しい問題で、僕たちの今の課題でもあります。少し前に、テーブルからデータを全て取得して、他のテーブルにデータを移し替えるようなスクリプトを書いて、テーブルを拡張しました。
岸本:今のところ成功していますが、原始的なやり方なので怖い部分はありますね。Cloud Firestoreには、データのエクスポートができないというデメリットがあって、バックアップする方法がないので……2。
星川:Firebaseはデータの変更が簡単にできてしまうので、バックアップできないのは大きなデメリットです。BigQuery用にデータを取得しているので、まったくバックアップできていないわけではないのですが、早く公式でサポートしてほしいですね。Cloud Firestoreはまだベータ版なので今は耐えるしかないですが。
岸本:ロールバックできないリスクがあるので、マイグレーションを走らせるときはさまざまな環境ごとに三重、四重に走らせてテストするようにしています。
―― Firebaseでの開発に欠かせないCloud Firestoreも、まだまだ課題が多そうですね。
岸本:はい。なので、Firebabseの使用を検討している場合は、まずはデータベース以外の機能から使ってみるのがいいと思います。データベース以外のFirebase AnalyticsやA/Bテストなどの機能は、運用中のサービスでもすぐに導入できておすすめです。
星川:適材適所で、利用するサービスは選んだ方が良いと思います。あと、基本はRDBなどを使用して、Redisのように読み込み専用としてCloud Firestoreを一部に導入するのはアリだと思います。リアルタイム性に優れているので、壊れてもいいデータを入れてキャッシュのように使用できます。
三浦:僕もその意見に賛成で、なにかを「1」から作るのであれば、基本のデータはMySQLなどに入れるようにした方がいいと思います。Firebaseには便利な機能がそろっているので、分析周りのサービスだけ使ってみても十分だと思います。
Cloud Functionsはテストの「仕組み作り」が何より重要
―― Firebaseに触れる上でおすすめのライブラリはありますか?
岸本:僕らは、ほとんど自分たちで作ったライブラリを使用しています。例えば三浦は「Tsuchi」というプッシュ通知のラッパーライブラリを作っていますし、僕はSwfitでCloud Firestoreのクエリを型安全に扱うための「Quiche」というライブラリを作りました。まだまだ技術が成熟されていなくて、ライブラリも確立されていないので、薄くてもいいから自分たちで作って導入するようにしています。
星川:我々の知識が深まるに連れて「このやり方はよくなかった」と分かるようになるので、実は作ったライブラリの約半分はもう使っていないんですよ。僕らが作ったライブラリ以外だと、Cloud Functionsのテストに使う「firebase-mock」がおすすめです。Cloud Functionsはオフラインだと動かないので、ローカルでテストしづらいんです。firebase-mockはライブラリ自体にバグがあるので100%信頼できるわけではないのですが(笑)、オフラインでもテストできるので重宝しています。
―― Cloud Firestoreと同様にCloud Functionsもまだベータ版ですが、なにか問題が起きたことはありますか?
岸本:「トランザクション処理を大量に行うと数回コケることがある」という問題が発生しました。在庫を減らす処理でデータベースロックがかかり、トランザクションの処理をするんですけど、商品を同時に100個ほど購入すると、20個ほどの商品が購入に失敗することがあって、本当に大丈夫なのかとヤヒヤしましたよ(笑)
星川:あとバッドノウハウとして、Cloud Functionsを使う際にユーザが何かを待つ仕組みをトリガーでやるようなことは避けた方がいいです。Cloud Functionsは数回発行される可能性があって、Komercoの開発中は決済が数回実行されてしまうバグがありました。Callable HTTPS Functionというセキュリティを担保したままAPIを実行できる仕組みが導入されたので、全てそれに置き換えました。
―― ECサービスで購入や決済にバグが起こるのは恐怖でしかないですね……。Cloud Functionsは課金周り以外には使用していないのでしょうか?
三浦:検索でも利用しています。ユーザーが商品を検索する際は全文検索する仕組みになっているので、データの更新があった場合に外部サービスのAlgoliaに投げるようにしています。
あとCloud Firestoreでは画像のリサイズをどうするか困っていたのですが、オリジナルサイズの画像をアップした際にCloud FunctionsでImageMagickを使ってリサイズをし、FirestoreのDocumentを更新するような仕組みにしました。
―― Cloud Firestoreと同じく、Cloud Functionsの事例もまだまだ少ないのが現状です。Komercoでは、どのような流れで開発しているのでしょうか?
星川:オンラインでテスト用のFirebaseにつないでロジックテストを実行します。そこでテストが通ったらプルリクして、CI(継続的インテグレーション)を回しています。開発用、テスト用、CI用、管理画面用、本番用など、いくつものFirebase環境を用意していますね。
岸本:Cloud Functions自体、コードを書いて上げるのは簡単なんですけど、こういった仕組みを作るまでが大変でしたね。
―― この仕組みを作ってからはスムーズに運用できるようになりましたか?
星川:そうですね。とはいえ、まだ不安点はあります。まずは、Firebase用の環境が乱立し過ぎているので、整理が必要です。あと、テストの環境は僕が構築したんですけど、ドキュメントが整備しきれていないので、他の人が作業しやすいよう改善していきたいと思っています。
簡単に開発できるからこそ、セキュリティには気を付ける
―― 他にFirebaseの開発で気を付けるべきポイントがあれば教えてください。
岸本:セキュリティ周りはかなり慎重になる必要があります。初期の設定だと誰でもデータ取得ができるので、「この条件ではデータが閲覧できない」とか、「Admin権限がないと書き込みできない」とか、細かく設定した方がいいと思います。Komercoでも権限周りは厳しく設定しました。
星川:権限周りだとデプロイもそうですね。Firebaseはコマンド一発でデプロイできるので、CIでしか本番にはデプロイできないようにしています。当たり前といえば当たり前な話ですが、何も設定しないとローカルから本番にデプロイできてしまうので、しっかりしておいた方がいいですね。
―― Komercoは課金機能もあるので、セキュリティや権限には特に気を使いそうですね。
星川:そうですね。実はリリース1カ月前に社内でセキュリティ診断を行った際、セキュリティ面での懸念点が発覚して、もっと厳しくしないとまずい! となりました。しかし、1カ月かけてしっかりセキュリティ面を整備・強化できたおかげで、リリースしてからは大きな問題はなく、落ち着いて運用できています。
岸本:FirebaseはAPIをいちいち叩くわけではなく、クライアント側からSDKを介して操作できるので、データベースの読み書きが容易にできてしまいます。なのでセキュリティルールをしっかりしておかないと、悪意あるユーザが金額を変えたり、ユーザの個人情報が閲覧できたり、そういうクリティカルな問題が発生する可能性があります。
星川:Komercoではそういった問題を回避する代わりセキュリティルールが複雑になってしまっていて、読んで理解するのすら難しくなってしまっています。複雑化すると逆にバグが起きかねないので、一部を自前でAPIでまかなった方がセキュリティ担保はできるかもしれませんね。
Firebaseは気軽に開発できる分だけ、ちゃんと作るのが難しいんです。だからこそ、扱いに気を付けなくてはいけないと考えています。
岸本:KomercoはECサービスなので、これからもセキュリティ面の不安とは慎重に向き合っていきたいですね。
Firebaseにおいてバックエンドの知識は不要なのか
―― これまでお話を聞いてきて、やはり「バックエンドエンジニアが不在でも開発できる」というのは、Firebaseを使う大きな利点であることが分かりました。一方で、バックエンドについて何も知らない人がFirebaseを使って開発するのは可能だと思いますか?
岸本:導入が楽な上に機能も多岐にわたるので、個人開発で裏側をFirebaseにしたり、画像データの置き場所を楽にするために使用したりするのであれば、アリだと思います。しかし、中規模~大規模サービスの開発となると練度や知識が必要になるので、場合によると思います。
星川:個人的な意見なんですけど、バックエンドをそこそこやっている人がCloud Functionsを使うのは、いろいろな面倒事から解放されていいと思いますね。ただ、バックエンドを知らない人がCloud Functionsを使い始めると“変なこと”をやっちゃう気がするかな。先ほども話したように、分析関係のみで利用するのは大いにありだと思います。
―― なるほど。やはりケースバイケースにはなりますよね。最後に、これからFirebaseを使ってKomercoをどう改善していきたいですか?
星川:KomercoはCtoCですが、買い手と売り手がチャットなどでやり取りする機能がないので、リアルタイム性に優れているFirebaseでそういった機能を作っていきたいですね。
三浦:今は「普通のECサービス」状態なので、もともとのサービスコンセプトに沿って作り手をもっと意識して「作り手の気持ちがユーザーに伝わるサービス」にしたいです。
技術的な面だと、僕はもともと全文検索の知識があったわけではないので、もっと上手に連携させて必要なデータを取得できるようにしたいです。これから必要になってくるであろうランキングやレコメンド機能の開発にも取り組みたいですね。
岸本:僕は先ほども話した通り、ECサービスだからこそ、セキュリティ関係はもっと気を使っていきたいですね。あとはFirebase Remote Configを使用したA/Bテストも、もっと行っていきたいです。
Firebaseでやれることをもっともっと増やして、ユーザーにもっと価値のあるものを提供できるサービスに成長させたいです。
取材:megaya megayaのブログ