#はじめに
備忘録として、Firebase Cloud Firestore(以下、Firestore)についてまとめていきます。
そもそもFirebaseが何なのか?というのは今回は割愛します。
#Firestoreを知る前に
データベースには大きく分類すると、RDBMS
とNoSQL
に分けることができ、前者はSQL
というコンピューター言語を使用して、データの書き込み・読み取りを行います。
対して、後者のNoSQL
は文字通り、SQL言語を使用せずにデータの書き込み・読み取りを行っています
。
主な違いは管理方法にあり、RDBMSは1つのキーに対して複数の付随するデータを管理
しているのに対し、NoSQLは1つのキーに対して1つの付随するデータを管理
しています。
・RDBMS 「1キー:複数の付随データ」
・NoSQL 「1キー:1つの付随データ」
FirestoreではNoSQLでデータが管理
されており、クラウドデータベース
になっています。
#クラウドデータベースとは
手元にサーバーやソフト等の環境を持たずにデータベースを利用することができるサービス
の事です。
これはデータベースに限った話ではなく、手元にサーバーやソフトなどの環境がなくても利用できるサービスはクラウドサービス
としてまとめられます。
この主な例として他にもGmail
やiCloud
などがあり、Firebase
も該当します。
どれも利用する側は環境構築を1からしなくても、インターネットに繋がっていればサービスを利用することが出来ます。
#Firestoreとは
Googleが提供しているNoSQLクラウドデータベース
です。
Cloud Firestore | Firebase
公式ドキュメントを見てもらうと分かるようにFirestoreではコレクション
、ドキュメント
等の用語が登場します。
###・ドキュメント
あらゆるデータを長期間保存する場所
です。
例えば、humanドキュメント
が作られた場合は下記のようになります。
📄human(ドキュメント)
first(フィールド): "Larry"(値)
last: "Page"
born: 1973
各ドキュメントにはキー(フィールド)
と値
のペアが含まれており、ドキュメントID
で識別されています。
ドキュメントIDは重複
せず、通常は追加と同時にランダムなIDが付与され、ユーザーIDなどの独自のキー等を自分で指定することも可能
です。
更に、ドキュメント内のデータをマップ(ドキュメント内で複雑にネストされたオブジェクト)で構造化
することも出来ます。
📄human
name:
first: "Larry"
last: "Page"
born: 1973
ドキュメントはJSON
に似ており、公式もJSONと基本的には同じ
と公言しています。
###・コレクション
複数のドキュメントをまとめるフォルダみたいなもの
です。
仕組みとしてはデータをドキュメントに書き込み、そのドキュメントをコレクションにまとめる
といった感じです。
公式ドキュメントの以下の画像がわかりやすいと思います。
(出典: Cloud Firestore データモデル | Firebase)
例えば、foodコレクション
を作成して、様々な食べ物を表すドキュメントを格納した場合このようになります。
🗂food(コレクション)
📄meet(ドキュメント)
kind(フィールド): "ChickenMeat"(文字列型の値)
Id: 12345678(数値型の値)
📄fruit
kind: "Apple"
Id: 87654321
Firestoreでは、Bool値、数値、文字列、タイムスタンプなど、様々なデータ型の値がサポートされています。
コレクションは、自分から作成・削除をする必要がなく
、最初のドキュメントを追加した時に勝手に作られ、コレクション内のドキュメントを全て削除すると自動的にコレクションも削除されます。
そして、コレクションにはドキュメントのみしか含めることができません
。なので、コレクションに対して生のフィールド
や他のコレクションを含める
ことは許されていません。
###・リファレンス
データベース内の場所を参照するだけの軽量なオブジェクト
です。
先ほどのfoodコレクション内のドキュメントを参照してみましょう。
🗂food
📄meet
kind: "ChickenMeat"
Id: 12345678
📄fruit
kind: "Apple"
Id: 87654321
let foodDocumentRef = Firestore.firestore().collection("food").document("meet")
これで、コレクション内のドキュメントを参照することが出来ます。
もちろん、コレクションへのリファレンスも作成可能です。
let foodDocumentRef = Firestore.firestore().collection("food")
コレクションリファレンス
とドキュメントリファレンス
は2種類の異なるもの
であり、それぞれ別の操作が可能です。
例えば、コレクションリファレンスを使用してコレクション内のドキュメントに対するクエリを実行
したり、ドキュメントリファレンスを使用して個々のドキュメントを読み書き
したりできます。
ドキュメントまたはコレクションへのパスを文字列として指定し、スラッシュ(/)
で区切ってリファレンスを作成することもできます。
let meetDocumentRef = Firestore.firestore().document("food/meet")
###・サブコレクション
例えば、メッセージとチャットルームを使ったチャットアプリがあったとします。
下記のようなroomsコレクションがあって、ここにメッセージを保存する場所
を指定しなくてはいけません。ですが、Firestoreのドキュメントは軽量
にする必要があり、膨大な数のメッセージを格納するのは厳しいようになっています。
🗂rooms
📄roomA
name: "my Room"
📄roomB
name: "dog talk"
.
.
.
そういう場合にはサブコレクション
を使用します。
これは、特定のドキュメントに関連付けられたコレクション
です。
roomsコレクション内の全てのルームドキュメントにmessageサブコレクション
を作成してみましょう。
🗂rooms
📄roomA
name: "my Room"
🗂message(サブコレクション)
📄message1(ドキュメント)
from: "taka"
msg: "Hello World!"
📄messsage2
from: "rio"
msg: "Hi!"
📄roomB
.
.
.
次のコードを使用してサブコレクション内のメッセージへのリファレンス
も作成可能です。
let messageRef = Firestore.firestore()
.collection("rooms").document("roomA")
.collection("message").document("message1")
更にサブコレクション内のドキュメントもサブコレクションを格納
できるため、深くネストできます。最大100レベル
までネスト可能です。
しかし、注意すべき点が2つあります。
#####①コレクションとドキュメントが常に交互になるようにしなくてはいけない
なので、コレクション内のコレクションやドキュメント内のドキュメントは参照できません
。
#####②ドキュメントを削除しても、その中のサブコレクションは削除できない
例えば、親ドキュメントを削除する時にサブコレクション内のドキュメントも削除する場合は手動で削除する必要があります。
#おわりに
Firestoreについてまとめました。
今回よく分かったことは困ったら公式ドキュメントを見た方が良いという事です。
次は、Firestoreのセキュリティルールについてまとめようと思います。