Cloud FirestoreはNoSQLでスキーマレスなので、任意のフィールドに対して任意の値を入れることができるのだが、
セキュリティルール的には、書き込み時にどのフィールドにどの型の値が入るのかしっかりチェックしたほうが良いのでその方法を。
is
演算子を使う
is
演算子を使うことでvalueが何の型かチェックできるようになる
文字列
is string
で判定する
allow create: if request.resource.data.name is string;
数値
数値はint
float
number
と、3パターンある
// ageがint型(整数値)以外だと拒否される
allow create: if request.resource.data.age is int;
// distanceがfloat型(浮動小数点数)以外だと拒否される
allow create: if request.resource.data.distance is float;
// numが数値以外だと拒否される
allow create: if request.resource.data.num is number;
注意なのは、floatの場合、 1.0
は許可されるが、 1
だと拒否されるので注意。
完全に整数値でないとならない場合はint
、そうでなければnumber
を使っておくのが吉
真偽値
is bool
で判定できる。
allow create: if request.resource.data.flag is bool;
たまにSwift(iOS)の感覚でいるとnumberでも判定できるんじゃね?って思ってしまうが、numberで判定することはできない。
日付
is timestamp
で判定できる
allow create: if request.resource.data.publishedAt is timestamp;
geo
is latlng
で判定できる
allow create: if request.resource.data.point is latlng;
配列
is list
で判定できる
allow create: if request.resource.data.members is list;
ただし、配列内の各要素の型が何であるかまでは判定できない。
連想配列(Object)
is map
で判定できる
allow create: if request.resource.data.userInfo is map;
ただし、連想配列のkeyやvalueの型が何であるかまでは判定できない。
参照(Reference)
is path
で判定できる
allow create: if request.resource.data.userRef is path;
※このブログを書いた現在、このルール文のシミュレートはうまくいかない。
型チェックがうまくいかないときのチェックポイント
型チェックが正しそうなのにうまく判定されない…というときは、
- 型名を間違えていないか
- 型名は
lower case
になっているか(Int
とかString
ではだめ)
あたりを見てみると良い。
ちなみに、ルールシミュレータで型を間違えて記述すると、不明なエラーを吐いて、以下の文章が表示される
An unsupported type identifier was used with the ‘is’ operator. Received XXX. Expected one of bool,constraint,duration,float,int,latlng,list,number,map,string,timestamp,path
… constraints
ってなんだろ。
まとめ
is演算子で事前に書き込む値の型をチェックすることで、書き込み時に想定と異なる値の書き込みがされないように防ぐことができる。
一方で、現状はList,Mapに関してはValueの型を縛ることができないし、forEach的な感じで配列内を走査して1つ1つチェックすることもできないのでその辺りは運用でカバーするしかない。