firebase realtime database入門 11

Databaseと聞くと、これから利用しようとするFirebaseがmBaaSであることを忘れてついREST(Client Server Model)で考えてしまいがちですが、大前提はMobile Platformなので、一度REST、RDBの考え方は捨ててみてください。. Help us understand the problem. Send edit request. On this page you will see the data that is currently stored in your Firebase Realtime Database. Copyright © 2019 en-japan inc. All Rights Reserved. Browse to the initial_messages.json file at the root of the repository, select it then click the Import button. 自己紹介 名前 古賀 友規 所属 株式会社ビズリーチ スタンバイ事業部/アプリエンジニア 出身地 福岡 3. こんなん作ってます 4. 投稿日:2018/11/07 ... サンプルアプリケーションを動かすためには、 Realtime Database 、 Firebase Authentication 、 Cloud Storage ... 【GCP入門編・第1回】エンジニア必読!今さら聞けない、Google Cloud Platform (GCP) とは? Firebase Realtime DBを実践に投入する. JSONで保存するfirebaseのDBでリアルタイムで同期されるのでチャットなどに便利。最近cloudfirestoreという別のDBができているがまだベータ版なのでrealtimedatabaseを使ったほうが無難かも。, 突然登場した$user_idですが、これは $location変数と呼ばれる特殊な変数です。頭に$を付けた好きな名前の変数を宣言すると、「その階層にあるノードのキー」がそこに入ります。 This will replace any data currently in your database. タイトルの 各Firebaseプロダクトの概要とチュートリアルを通しての実際の実装利用方法, Firebase Authentication では、パスワード、電話番号、一般的なフェデレーション ID プロバイダ(Google、Facebook、Twitter)などを使用した認証を行うことができます。また、OAuth 2.0 や OpenID Connect などの業界標準を使用しているため、カスタム バックエンドと簡単に統合できます。, ユーザーが初めてアプリに登録するときに、利用可能な情報を使用してユーザーのプロフィール データ(一意の ID、メインのメールアドレス、名前、写真の URL から構成される基本プロパティ)が設定されます。, 注: 認証されたユーザーは Firebase Realtime Database と Cloud Storage に対して、デフォルトでデータの読み取り、書き込みができます。, Firebase Realtime Database は NoSQL クラウドホスト型データベースです。データはすべてのクライアントにわたってリアルタイムで同期され、アプリがオフラインになっても引き続き使用できます。, 注: 新しくプロジェクトを開始する場合、ほとんどのケースで Cloud Firestore のご利用をおすすめします。, Firebase Realtime Database ルールでは、データベースへの読み取り / 書き込みアクセス権を持つユーザー、データが構造化される仕組み、存在するインデックスを決定します。, Cloud Storage for Firebase は、Google 規模で構築された、強力かつシンプルでコスト効果の高いオブジェクト ストレージ サービスです。写真や動画など、ユーザーが作成したコンテンツを保管、提供する必要のあるアプリ デベロッパー向けに構築されています。, デベロッパーは Cloud Storage 用の Firebase SDK を使用して、クライアントから直接ファイルのアップロードとダウンロードを行います。ネットワーク接続がよくない場合、クライアントは動作が停止したところから再試行できるため、ユーザーは時間と帯域幅を節約できます。, Cloud Storage 用の Firebase セキュリティ ルールは、Firebase Realtime Database ルール同様、わずか数行のコードで、Cloud Storage リクエストを特定のユーザーに限定する承認ルールや、アップロード サイズを制限する承認ルールを作成できます。加えて、ファイル名とパスの検証、contentType や size などのファイル メタデータのプロパティの検証といったデータ検証にも使用できます。, 注: Cloud Storage はデフォルトの Google App Engine アプリと同じ Google Cloud Storage バケットを使用します。, これまで紹介した Firebase Authentication、Firebase Realtime Database、Cloud Storage for Firebase は、それぞれ Cloud Functions を利用することで機能を拡張することができます。一般的なユースケースは以下です。, 重要: Cloud Storage バケットのロケーションと関数のロケーションとの距離によっては、ネットワーク レイテンシが大幅に増加する可能性があります。パフォーマンスを最適化するために、関数のロケーションは適切な場所に指定してください。, Codelabとこちらのサンプルコードを参考にして、Firebase Authentication、Firebase Realtime Database、Cloud Storage for Firebase を試してみましょう。, 次にサンプルアプリケーションをデプロイするために Firebase プロジェクトを作成します。, 作成したFirebaseプロジェクトにクローンしたAndroidアプリを追加します。, Firebase Authentication を利用するために SHA-1 を追加します。SHA-1は以下のコマンドで発行。, Sign-in method からログイン プロバイダとして Google を有効化し、保存をクリックします。, クローンしたプロジェクトをAndroid Studio で開き、Enable Authentication の Add Firebase Auth dependency 以降を参考に、, Android emulator を起動します。Sign-In with Google の画面が確認できました。, Read Messages の Import Messages を参考にチャットで予め表示するメッセージを追加します。, Google アカウントで Sign-In に成功すると、先ほど Realtime Database に追加したメッセージが表示されました。, Send Messages の Implement text message sending を参考にテキストメッセージ送信機能を実装します。ここで生成されるメッセージIDはリストの最後に追加されるようにシークエンシャルです。, Send Messages の Implement image message sending を参考にテキストメッセージ送信機能を実装します。, “ + “ ボタンをクリックすることで、テキスト / 画像を送信できるようになりました。. こんにちは、昔cocos2dでiphoneゲームを作っていた中村です。 最近またiphoneアプリを作っています。 作成にあたりfirebaseの「Authentication」、「Realtime Database」を使ったので、これらの概要とメリットを紹介します。 今回は以下を学習ポイントとしてiphoneアプリをストア公開までやってみまし … Revisions Edit Requests Show all likers Show article in Markdown. In the overflow menu of the Database select Import JSON. Cloud Firestoreのrulesのテストを全てローカルエミュレータを使うように書き換えた話, Laravel実践入門! シンプルなREST APIを実装して学ぶ、多機能なPHPフレームワークの使い方, カオスエンジニアリングによる負荷試験を導入するクックパッドが学んだこと 耐障害性の仮説と検証, Kubernetesのモダンな活用法 - 設計メソッドと、Virtual Kubeletで実現するサーバーレス化を学ぼう, 提供されているモジュールやSDKを利用することで、APIを書かずにデータベースにアクセスが可能, Firebase js-sdk: admin, cloud-function, cloud-firestore, ドキュメントの保存をトリガーにして実行するのではなく、任意のタイミングで処理を実行したい, ルールでは、フィールドのバリデーションをかけることもできるので、不正な値が書き込まれることを未然に防ぐことができる, 読み書きの処理を各プラットフォームで記述しないといけないので、頑張って統一する必要がある, 関数内ではadmin権限でデータベースを操作できるので、ルールの影響を受けることなくやりたいことが実現できる. By following users and tags, you can catch up information on technical fields that you are interested in as a whole, By "stocking" the articles you like, you can search right away. Report article. firebase database は比較的新しいサービスなだけに rule の例がそんなに多くないので参考になれば幸いです。 他にも思いついたら追記していきたいと思います。 追記. Help us understand the problem. Firebaseでは、バックエンドやインフラに精通したメンバーがいなくても、モバイルやWebフロントの開発に集中できます。Authentication、Firestore、Cloud Functions、さらにセキュリティルールまで、クックパッドの岸本卓(@_sgr_ksmt)さんが、実践的に解説します。, Firebaseをご存じでしょうか? Firebaseを利用したことはありますか? 今回は「Firebaseをこれから使ってみたい!」「絶賛使っているけど、初めてでどう開発したらいいかよく分からない……」という方を対象に、実践的な入門という形で説明していきます。, Firebaseは、2011年にFirebase社がサービスを開始し、2014年にGoogleが買収したMBaaS(Mobile Backend as a Service)です。, Firebaseでは、リアルタイムでデータを同期できるCloud FirestoreやRealtime Databaseといったデータベース、プッシュ通知を簡単に実装できるFirebase Cloud Messaging、サーバーレスに何かのイベントをトリガーに関数を実行するCloud Functions for Firebaseといった機能を利用できます。, Authentication、Hosting、Cloud Storage、Crashlytics、Performance Monitoring、Test Lab、Analytics、Predictions、A/B Testing、Remote Config、Dynamic Links、App Indexing、In App Messaging、ML Kit, サービスが開始された当初にはまだなかった機能やβ版だった機能も多かったのですが、今ではほとんどの機能がGA(Generally Available)となっており、Firebaseが使われるシーンも増えてきたように思えます。, Firebaseの良いところは、自分自身にバックエンドやインフラの知識がなかったり、精通したメンバーがいなかったりする中でサービスを開発することになっても、Firebaseがさまざまな機能をあらかじめ提供してくれているので、サーバーの構築やインスタンスの立ち上げなどを気にすることなく、モバイルやWebフロントの開発に集中できることです。, 自分でいちからサーバーを立ち上げたり、認証基盤を作成したり、プッシュ通知を配信する仕組みを作る手間と時間を短縮できることは、とても大きいと思います。, 実際に筆者が携わっているプロダクトでは、Firebaseを使って、iOSエンジニアのみでサービスの開発からローンチまで行うことができました(詳しくは次の記事を参照)。, また、Firebase自体の開発も盛んで、機能改善や新機能が次々と搭載されるため、Firebaseで実現できる開発の幅がどんどん広がっています。 今携わっているプロダクトでも、開発当初では機能上の制約や、そもそも提供されておらず実現できなかった機能が、今では当たり前のように実装できるようになった、ということも少なくありません。, さらに、Firebaseの利用を始めること自体は無料で、有料プランでも従量課金制のほか、毎月25ドルの定額プランも用意されています。, 「これから何かアプリケーションを開発したい!」という人には、筆者は強くFirebaseの利用をオススメします。 作成するアプリケーションの特性にもよりますが、以下の恩恵を受けることができます。, 個人開発をする人にとって、手間とコストを大幅に削減できるのはとても大きいと思います。, そして、Firebaseは無料で利用できる機能の範囲が広く、また従量課金プランに変更したとしても、そこまで料金がかかりません(規模によります)。, 一昔前のFirebaseでは、MVP(Minimum Viable Product)や検証目的で作るには適している一方で、プロダクション品質まで高めるのは難しいと言われることもありました。, しかし、ほとんどの機能がGAとなり、サービスの安定性も高くなったこともあり、採用しない手はないだろうと思います。, 途中からでは、Cloud Firestoreといったデータベースを導入することは難しいでしょうが、AnalyticsやPredictionsによる分析や、Cloud Messagingを用いたプッシュ通知の配信など、効果を発揮する機能があります。, また、Googleが買収したFabricのCrashlyticsがFirebaseに統合されたり、Performance Monitoringといった機能が用意されたりしたことで、クラッシュしている箇所やパフォーマンスに問題がある部分を特定し、改善していく手助けになります。, Firebaseを使った開発で特に重要となる3つの機能について、簡単に紹介します。 このAuthentication、Cloud Firestore、Cloud Functionsを組み合わせるだけでも、簡単にサービスを構築することが可能です(本記事の後半で紹介します)。, Firebaseには認証を行う機能が備わっており、認証自体を自分で実装しなくて済みます。, 認証方法としては、メールアドレス等を一切必要としない匿名認証から、メールアドレスでの認証、各種サービス(TwitterやFacebook)を使った認証などがあります。, 特に、次のCloud Firestoreなどを使うには、認証済みユーザーであるかどうかを検証することがベースとなるため、Authenticationの使用が必須となるでしょう。, Cloud Firestore(以下、Firestore)は、ドキュメント指向のNoSQLデータベースです。, Firestoreを理解する上で必要不可欠なのが、「コレクション」と「ドキュメント」です。 この関係についてはFirebaseの公式ガイドと図を参考にしてください。, また、リアルタイム性も兼ね備えており、ドキュメントに変更があった場合、クライアント側でリッスンしておくと、変更を即座に受け取ることも可能です。, なお、Realtime Databaseで特定のノードを取得する場合に子ノードも全て取得するため非効率になるケースがありますが、Firestoreでドキュメントを取得する際には配下のサブコレクションまで取得してしまうことはありません。, Cloud Functionsは、JavaScriptで記述された関数を実行する機能です。, ファンクションには、Firestoreにドキュメントが書き込まれた・更新されたといったイベントを元に実行されるもの、定期実行のもの、HTTPSリクエストで実行できるものがあります。, トリガーを起点にFirestoreのドキュメントに変更を加える、Cloud Messagingを用いてプッシュ通知を送る、外部サービスのAPIを叩くといったことが可能になります(CLoud FunctionsからFirebaseサービス外への通信が発生する場合、無料プランでは実行できず、有料プランへの切り替えが必要)。, ここからはサンプルアプリケーションを通して、Firebaseを使った開発の仕方や設計を説明していきます。 認証からデータベース、Cloud Functionsにセキュリティルールといった形で、実際にサービスを公開するまでに必須となる内容を、実践的に学ぶことができます。, 取り上げるサンプルは、とてもシンプルで簡素なフリーマーケット型のショッピングアプリです。, 筆者がiOS開発を得意としていることもあり、作成するサンプルはiOSアプリで開発言語はSwift、バックエンドはNode.jsでTypeScriptです。 使用した開発環境は、以下の通りです(できる限り執筆時点の最新バージョンを使用しています)。, 上記のリポジトリで公開しているサンプルを実際に動かすには、次のセクションから説明するように自身でFirebaseプロジェクトを作成することと、関連する設定ファイルが必要です。 iOSアプリ側の設定ファイルはGoogleService-Info.plistで、バックエンド側はadmin_sdk.jsonです。, まず、Firebaseのプロジェクトをセットアップしましょう。 Firebase consoleにアクセスして、「プロジェクトの追加」から新たにプロジェクトを作成します。, このウィンドウで、プロジェクト名、プロジェクトID、Firestoreとアナリティクスで使用されるロケーション(リージョン)を指定します。, プロジェクトIDとロケーションは後で変更できないので、注意が必要です。 また、今では東京リージョン(asia-northeast1)や大阪リージョン(asia-northeast2)を 選択できるので、国内に向けたサービスを作りたい場合は選ぶとよいでしょう。, iOSアプリに関しては、通常通りXcodeプロジェクトを作成したのち、FirebaseをCocoaPods経由でインストールすれば、おおむねセットアップは完了します。, 今回は、Firebase iOS SDKのうちCore Auth Firestore Functionsの4つを扱うので、次のようなPodfileを記述して、pod installを実行します。, CocoaPodsそのものの利用について知りたい方は、次のエントリーなどが参考になります。, 今回はCloud Functionsと、Firestoreのセキュリティルールをデプロイする必要があるので、バックエンド側のセットアップも行います。, まず、npmあるいはyarnで、firebase-toolsをインストールします(筆者はyarnを使います)。 firebase-toolsは、マシンのグローバル領域にインストールしてもよいですし、プロジェクトにインストールしてもかまいいません。, 筆者は、複数プロジェクトそれぞれで独立してバージョン管理ができるように、プロジェクト毎にインストールするようにしています。, firebaes-toolsがインストールできたら、セットアップを実施します。 以降はプロジェクトにfirebase-toolsをインストールした場合のコマンド例です (グローバルにインストールした場合、プレフィックスのyarnは不要)。, このように、まずFirebaseにログイン(firebase login)しないと、セットアップ(firebase init)やデプロイは実行できません。, Firebaseのセットアップは対話式に進みます。 セットアップしたいプロジェクトを選択し、以下のように答えていきます。, もしセットアップしたいプロジェクトが選択項目に現れないときは、firebase loginでログインしたアカウントに閲覧権限があるかどうか確認してください。, ここまでが済むと、指定したディレクトリに、functionsディレクトリができ、次のファイルが含まれていると思います。, という理由から、さらに少し手を加えます。 具体的には、次の3つのファイルを書き換え, package.jsonには、次のようにbuildとdeployのコマンドを記述しておきます。, buildは、functionsのソースコードをトランスパイルした.jsファイル、package.json、admin_sdk.jsonをdistディレクトリにコピーするコマンドになっています。 deployでは、firebase.jsonで指定したdistディレクトリの内容を元にデプロイを行います。, ここまでで、iOSアプリとバックエンドの両方で開発を進めるセットアップが一通り完了しました。 構成に迷ってしまった場合は、サンプルプロジェクトと照らし合わせて確認してみてください。, プロジェクトがセットアップできたら、Firebase consoleで「Authentication」を選び、「ログイン方法」の項目を開きます。 ここにはFirebaseで認証するためのログイン手段が並んでいます。, 今回は匿名認証を使用したいので、「匿名」の項目を有効にします。 これにより、アプリ側からメールアドレス等不要で認証させることが可能になります。, 以降、他の認証方法を使用する場合は、同様にこの画面から有効にする必要があります。 新規で認証方法を増やす場合にエラーが発生した場合には、設定を有効にしているかどうか見直しましょう。, なお、今回のサンプルでは使いませんが、TwitterやFacebookといった認証方法を使ってのログインも可能になっています。, 次に、データベースをセットアップをします。 Firebaseには、リアルタイムでデータを同期できるクラウドベースのデータベースが2つありますが、今回はRealtime Databaseではなく、Firestoreの方を使用します。, Firebase consoleで「Firestore」を選択するときに、セキュリティルールがどちらかを聞かれますが、ひとまず「テストモード」を選択します。 これにより、(一時的に)全てのドキュメントへのアクセスが可能になります。, ロックモードを選択すると、全てのドキュメントに対する操作は行えない状態になっているので、別途セキュリティルールを記述する必要があります (セキュリティルールに関しては後述)。, 登場するドキュメントは、User(ユーザー)、Product(商品)、CartItem(カート)、Order(注文情報)の4つで、構成は以下のようになっています。, また、Productドキュメントにはそのドキュメントの作成者(User)のドキュメントのパス(reference)を、CartItemドキュメントにはカートに入れた商品(Product)のドキュメントのパスを持たせるようにしています。, なお、今回はサンプルのため簡略化していますが、本格的にサービスを運用する場合は、次のような設計の追加が必要になるでしょう。, 決済に関わる部分の情報(カード情報等)は、適切にセキュリティルールで保護した上でFirestoreに持つのもよいですし、自社の決済基盤やStripeを活用するのもよいでしょう。, モデルの設計にあたっては、Firestoreのようなドキュメント指向のNoSQLとRDB(リレーショナルデータベース)との違いや、それぞれでできること・できないことを意識して設計する必要があります。, RDBでは、データを正規化し、JOINやGROUP BYといったSQLの操作で目的のデータを結合して取得することが定石となっています。 それに対して、Firestoreではデータを冗長化しておいたほうがよかったりします。, Firestoreのクエリにも絞り込みの機能が備わっているものの、RDBと違って結合や集計の操作を行うことが現状できないため、なるべく簡単なクエリ操作でデータを取得できる設計にしておくとよいでしょう。, また、結合などの操作が行えないため、「Aドキュメントを取得した後に、関係のあるBドキュメントをあらためて取得する」といった操作が発生するケースがあります(クライアントサイドジョインと呼ばれたりします)。 いわゆる「N+1問題」のような状況が発生するため、規模が大きくなるほど問題化することも考えられます。, クエリを活用し、適切な範囲を取得して読み込むようにロジックを調整すれば、大きな問題にはならないと筆者は思っていますが、読み込み回数の増加を少しでも防ぐため、あらかじめ「AのドキュメントにBのドキュメントの情報を書いて、冗長化する」といったデータ操作をすることもあります。, 具体的な例を挙げましょう。次のように参照を持たせる方法では、productドキュメントの一覧を取得した後に、それぞれのownerの参照を元にユーザーの情報を取得してUIに反映させるというように、N+1回の読み込みが必要になります。, 対して、次のように冗長化したデータを持たせた場合には、productドキュメントを取得した時点でユーザーの情報があるので、そのままUIに反映することができ、productの一覧を読み込むだけで済みます。, ただし、冗長化するデータの大元であるユーザーのドキュメントに更新があった場合は、冗長化した部分も更新する必要があり、読み込みは減るものの、書き込みは必然的に増えますし、更新を忘れるとデータの整合性が保てなくなります。, このような「冗長化したデータ構造を作る」ため、Firebaseにはバッチによる一括書き込み、トランザクションを用いた書き込み、Cloud FunctionsのFirestoreイベントトリガーといった機能が備わっています。 これらを活用することで、データの整合性を担保しつつ、データを冗長化して持たせることが可能になります。, 一方で、全てのデータを冗長化して持つべきかといえばそうではなく、データの読み込みの頻度、冗長化される元となるドキュメントの更新頻度によって、適切に判断する必要があります。 また、冗長化して配置する箇所が増えれば増えるほど、冗長化して配置・更新するための裏側の処理が複雑になるので、かえって設計が大変になってしまうこともあります。, 今までRDBを使ってきた人にとって、同じようなデータが冗長的に配置されることは、初めのうち違和感があると思います。 その違和感も、慣れてくるとなくなり、冗長化すべきかそうでないかも見極められるようになってくると思います。, Firestoreで実現できるモデルの構成に関しては、次の記事やスライドがとても参考になります。, Cloud Firestoreを実践投入するにあたって考えたこと#CloudFirestore データベース設計, ここから、Firebaseの機能を利用したコードの書き方を解説していきます。 まず、Authenticationを利用した認証について説明します。, より詳細な実装は、前述のリポジトリにあるFirestoreModel.swiftを参照してください。, AuthのaddStateDidChangeListenerを使って、ユーザーが認証済みであるかどうかを確認します。, このメソッドで、最初の呼び出し時と、以降の認証状態が変化したときに確認することができます。 これで、認証済みであれば認証後の画面を、そうでなければ認証前のサインアップ画面を出すことが可能になります。, はじめは認証情報がないため、次のようなサインアップ画面を準備します。 名前を入力してもらい、サインアップしてもらいます。, Result型を使いやすくするため、次のラッパーを用意しています(サンプルのResult+.swiftを参照)。, 認証ができたら、その認証情報を使ってUserドキュメントを作成します。 基本的には認証で得られたuidをそのままUserドキュメントのドキュメントIDとして用いるとよいでしょう。, Firestoreのドキュメントの取得や書き込みに関しては、SDKそのままのインターフェースではやや扱いづらいことがあります。, 今回のプロジェクトでは使用していませんが、Firestoreのモデルを扱いやすくするOSSが公開されているので紹介しておきます。, ユーザー(Userドキュメント)の処理に続いて、商品(Productドキュメント)とカート(CartItemドキュメント)の扱いを実装していきましょう。, 実際のショッピングサービスであれば、出品するユーザーがフォームに従って情報を入力し、商品を登録しますが、今回は簡易化のため既に商品情報は用意してあり、出品時にはランダムな商品情報に出品者自身のUserドキュメントのパスを付与し、Firestoreに保存します。, 次に、登録した商品の一覧を表示できるようにします。 ドキュメントの一覧を取得する方法には、一度だけ取得するgetと、変更をリッスンし続けるlistenがあります。 今回はlistenを用いて、変更があった場合に一覧を更新します。, ドキュメントの一覧を取得する際にはクエリを指定でき、対象のドキュメントを絞ったり、並び替えたりできます。 次のコードでは、クエリにpublishedTime(公開日時)で降順、さらに最大取得数が100という条件を付けて取得しています。, 常にリッスンしているので、商品を登録するとすぐさま変更を受け取り、商品の一覧を更新することができます。, 続いて、カートに商品を追加します。先程の商品の登録と同様に、ドキュメントを指定の場所に作り、保存する流れになります。, カートは、商品を購入するユーザーに紐付き、他のユーザーから干渉されるドキュメントにはならないため、Userドキュメントのサブコレクションとして実装するのがよいでしょう。 具体的には、users/{user_id}/cart_items/以下にドキュメントを作成します。, 既に同じ商品をカートに入れている場合は、既存のCartItemのquantityを更新します。, なお、数量を更新する際にはquantity + 1とするのではなく、FieldValue.increment()を使うとよいでしょう。 number型のフィールドを、安全に増減させることができます(減らすときは負数を代入)。 詳細は、公式ブログで次の記事を参照してください。, Incrementing Values Atomically with Cloud Firestore - The Firebase Blog, カートに入っている商品の一覧を表示するには、Userドキュメントのサブコレクションであるcart_itemsコレクションのドキュメントの一覧を取得します。, 取得したCartItemドキュメントには数量とProductドキュメントのパスがありますが、Product自体の情報は持っていないので、画面に商品画像や商品名を表示するには、CartItemドキュメント毎にProductドキュメントを取得する必要があります。, 今回のケースでは、Productドキュメントにある金額・名前・在庫数といった情報が変わる可能性があるため、CartItemドキュメントに情報を書き写すのではなく、Productドキュメントのパスを持っておいて、最新の情報をその都度、取得する方が適しています。, それぞれのユーザーがカートに入れる商品の数もたかだか数十個程度でしょうから、いわゆる「N+1問題」もそこまで大きな問題にならないのではと思います。, カートに入れた商品を削除するのはとても簡単で、cartItemドキュメントのパスに対して、.delete()を呼んでやるだけです。, 別の方法としては、ドキュメントにisActiveといったbool値のフィールドを持たせて、そのフラグを更新する方法もあります。, 物理的にデータベースから消去するのが好ましくなく、論理的に削除状態にしたい場合は、こちらを検討してみるとよいでしょう。, ここまでで商品を登録し、カートに入れたり外したりできるようになりました。次に、いよいよカートの商品を購入してみましょう。, 購入処理に関しては次のような要件が求められるため、Cloud Functionsの呼び出し可能なHTTPSファンクション(Callable HTTPS Functions)を利用します。, 呼び出し可能なHTTPSファンクション(functions.https.onCall)が、ただのHTTPSファンクション(functions.https.onRequest)と異なる点は、クライアントからリクエストを送信する際に、Firebaseの認証情報が自動的に付与されることです。 これによって、関数実行時に認証情報を検証できるため、より安全な呼び出しが可能です (呼び出し可能ファンクションが実装されるまでは、自前で認証情報を含めて呼び出す必要がありました)。, これはindex.tsに直接ではなく、purchase.tsという別ファイルに書くことにします。, 商品の在庫確認と在庫を減らす処理は、同時に複数のアプリから実行されても問題ないように、トランザクションを張る必要があります。 それによって、仮に同じ商品が同時に購入されようとしても整合性が担保でき、在庫切れになったのに購入できてしまったというケースを防ぐことができます。, トランザクションを張るには、FirestoreモジュールのrunTransactionを実行します。, また、最後に作成するOrderドキュメント(注文情報)は、次のようなデータになるため、, 購入当時のProductドキュメントの情報をSnapshotProductとして書き写します。, これは、先ほど説明したCartItemドキュメントが、書き写すのではなくパスを持っていたことと対照的です。, さらに、ファンクションの定義の最初にある.runWith()と.region()では、Cloud Functionsのトリガーに対して、実行時のメモリやタイムアウト、リージョンを指定できます。 ここではFirestoreのリージョンを東京で作成しているので、それに合わせています。, ファンクション内でAdmin SDKを使うため、最初にセットアップする必要があります。 詳細は公式のドキュメントを参考にしてください。, デプロイしたファンクションをiOSアプリから呼び出すには、次のようなコードを記述します(サンプルのPurchaseRequest.swiftを参照)。, ここまでで一通りの機能がそろったので、セットアップ時に「テストモード」で構築したCloud Firestoreのセキュリティルールを、強固なものに変更しましょう。, まず、データモデルの構成で説明したそれぞれのコレクション・ドキュメントに対して、必要なルールの条件をまとめてみます。, なお、ドキュメントのreadやwriteは、それぞれget list create update deleteといったオペレーションに分解でき、細かく設定できます。, Productドキュメント(/products/{product_id})の条件:, CartItemドキュメント(/users/{user_id}/cart_items/{cart_item_id})の条件:, Orderドキュメント(/users/{user_id}/orders/{order_id})の条件:, Firestoreのルールは原則として、記述のないドキュメント・コレクションに対するアクセス権は拒否されるようになっています。 この例では、Userドキュメントの削除や、全く関係のないcitiesコレクションに対するドキュメントの書き込みは拒否されます。, このため、今後新しいドキュメントを設計して読み書きする場合には、それに対応したルールを追加していく必要があります。, ここから骨組みに対してルールを構築していきますが、そのために便利な関数を定義します。, セキュリティルールでは独自に関数を組むことができ、関数を活用することで分かりやすく、後でメンテナンスのしやすいルールを構築できます。, また、updateの条件では、しばしば「変更前後でフィールドの値が変更されていないこと」を条件に書きたいケースがあります。 そういうときは、次のように書くとよいでしょう。 この例は、updateの操作のときに、Productドキュメントのパスが書き換わっていないことを確認するための条件です。, これを加えることで、意図しないProductドキュメントやその他のドキュメントのパスに書き換えられる問題を防ぐことができます。 update操作に対するルールを書くときには、どのフィールドが書き換え可能で、どのフィールドは書き換え不可なのか検討しておきましょう。, Cloud Firestoreのruleで`update`の条件を書く時に気をつけたいこと - Qiita, 上記の関数とテクニックを組み合わせて構築すると、最終的に次のような構成になります。, ルールが記述できたら、コマンドライン経由でFirebaseにデプロイします。 セキュリティルールのみをデプロイする場合は、--only firestore:rulesを付けます。, デプロイした後、1分ほどで設定が反映されるでしょう。 ルールをデプロイした後には、正しく動作するかを確認してみましょう。, ここで「どのくらいセキュリティルールを書けばいいの?」という疑問が出てくるかと思います。次の順で優先度を高くして、書くとよいでしょう。, 最も防ぐべきは、意図しないユーザーによる不正な読み取りや、意図しないデータへの書き換えです。, Firestoreのセキュリティルールに関してより詳しく学びたい方は、筆者の記事ですが、以下が参考になると思います。, Firestoreでセキュリティルールを書かないで、全てCloud FunctionsのHTTPSファンクション(ないしは呼び出し可能なHTTPSファンクション)でデータをやりとりすることもできます。それぞれ、次のようなPros/Consがあります。, 個人的には、次のような場合はルールを記述せず、閉じた状態にして、Cloud Functionsを活用するようにしています。, それ以外に関しては、適切なルールを敷いた上で、クライアントに提供されているSDKを介して読み書きを行うようにしています。 その方が読み書きの速度も早く、リッスンして変更を常に受け取るのも容易です。, Firebaseの紹介にはじまって、Authentication・Firestore・Cloud Functionsを組み合わせた実装をサンプルを通して説明し、セキュリティルールまで解説しました。, この記事が、まだ一度もFirebaseを試したことがない方や、どのように設計するか分からない方の手助けになればと思います。, 「更新通知を受け取る」をクリック!ブログの更新通知をメールやアプリで受け取ることができます。, 「エンジニアHub」は、「20代と30代の若手Webエンジニアを応援する」をテーマに、若手Webエンジニアの活躍の様子や、最新の技術情報/Tipsを広くお届けするためのWebメディアです。エン・ジャパン株式会社と株式会社はてなが共同で作った編集部にて運営しています。, Firebase入門 フリマアプリを作りながら、認証・Firestore・Cloud Functionsの使い方を学ぼう!, tsc && cp package.json ./dist && cp config/admin_sdk.json ./dist, [.quantity: FieldValue.increment(Int64(1))], // トランザクションを利用して、カートにいれた商品の在庫があり購入可能かを確認する, 'There is less stock than the quantity to buy'.

ショートボブ ストレート 50代 5, Nrtテスト 過去 問 7, 酒井法子 息子 学校 12, Daydream Warrior 歌詞 パート 6, Cuda 画像処理 ライブラリ 5, 北欧神話 武器 剣 10, Survival ジャニーズwest 歌割り 11, ずっと真夜中でいいのに 歌詞 ハゼ 4, 高嶋ちさ子 父 会社 12, ヨシキリザメ アオザメ 違い 16, Aviutl 音mad スクリプト 53, ルームメイト ソラ 降板 11,