Firestore のサブコレクションを使うべきとき
前置き
あるコレクション X と別のコレクション Y がいわゆる「1-to-n」の形をとるとき、 Firestore ではサブコレクションを使う方法と使わない方法がある。すなわち、
- Y を X のサブコレクションにする方法
- サブコレクションは使わずに、 Y のドキュメントに X の ID を保持する方法
である。
Firestore では現状、方法 1 の方が制約が多くて使いづらいので、どう考えても方法 2 が良いと個人的に思っていたというか、むしろなぜサブコレクションというものがあるのか分かっていなかった。ところが今日、ちょっとだけ良いところに気づいたので書き残しておく。
セキュリティルールにおけるメリット
Y を X のサブコレクションにすると、セキュリティルールで Y のドキュメントにアクセスすることなく X の ID を扱えるというメリットがある。これは get
よりも list
の場合により効果を発揮する。
例えば、「ユーザーは自分の書いたポストならば一括で取得できるが、他人の書いたポストは1個ずつしか取得できない」というルールを定義したいとする。これはポストに対する list
に、リクエストユーザーと同じユーザー ID であれば真、そうでなけば偽となるようルールを書けば良い。
このときポストがユーザーのサブコレクションなら、ポストのルール内でユーザー ID を扱える。なぜなら、ポストのドキュメントパスの中にユーザーの ID が含まれているから、単に文字列をパースするだけで得られるからだ。
一方ポストがユーザーのサブコレクションでない場合、ユーザー ID を得るためにはポストのドキュメントを取得しなければならない。これでは要求したポストのドキュメント数に比例して時間がかかる事になるし、そもそも 取得できるドキュメントの数には制限があるので、10 件ずつ Paginate する必要があるかも知れない。
所感
このように限られたユースケースではあるものの、方法 1 でしか上手く扱えないケースは確かに存在する。しかし、誰でもリストできる(あるいは誰もリストできない)というリソースであれば、方法 2 を使うのが懸命だと思う。
💭 他にもサブコレクションを使った方が良い理由があれば知りたいので、コメントしてくださると嬉しいです。
Discussion