Announcing the Firestore Security Rules Simulator!のアナウンスで、Firestoreのルールでget()``exists()``getAfter()
の呼び出し回数が大幅に増加したようなので実際に試してみた。
事の発端
これ
Firestoreのルール、get,exists,getAfterの呼び出し制限の上限が3→10に上がったって書いてあってシミュレータでgetを20個くらいかいてやってみたけど成功ってなって制限超えてるかまでは分からなさそうな雰囲気だった
— su- (@sgr_ksmt_dev) 2018年6月21日
検証してみる
実際に使われるルールとは程遠いが、以下のように適当にpost
モデルを11個ほど生成して、それぞれのドキュメントが取得できてnull
ではないというルールを愚直に書いた
service cloud.firestore {
match /databases/{database}/documents {
function getPost(postID) {
return get(/databases/$(database)/documents/post/$(postID));
}
match /post/{postID} {
allow create: if getPost('post_id_1').data != null
&& getPost('post_id_2').data != null
&& getPost('post_id_3').data != null
&& getPost('post_id_4').data != null
&& getPost('post_id_5').data != null
&& getPost('post_id_6').data != null
&& getPost('post_id_7').data != null
&& getPost('post_id_8').data != null
&& getPost('post_id_9').data != null
&& getPost('post_id_10').data != null
&& getPost('post_id_11').data != null;
}
}
}
これで、client側からpost
モデルを作成しようとすると、
get()
が10回まで→ 成功get()
が11回を超える→ 失敗
となった。
同一pathのドキュメントを11回取得した場合は?
service cloud.firestore {
match /databases/{database}/documents {
function getPost(postID) {
return get(/databases/$(database)/documents/post/$(postID))
}
match /post/{postID} {
allow create: if getPost('post_id_1').data != null
&& getPost('post_id_1').data != null
&& getPost('post_id_1').data != null
&& getPost('post_id_1').data != null
&& getPost('post_id_1').data != null
&& getPost('post_id_1').data != null
&& getPost('post_id_1').data != null
&& getPost('post_id_1').data != null
&& getPost('post_id_1').data != null
&& getPost('post_id_1').data != null
&& getPost('post_id_1').data != null;
}
}
}
ドキュメントにも書いてあるが、
同じドキュメントに対する複数のリクエストは、個別のリクエストとしてカウントされません。
ということなので、この場合は問題ない。
get()
と exists()
を混ぜて11回呼び出す
service cloud.firestore {
match /databases/{database}/documents {
function getPost(postID) {
return get(/databases/$(database)/documents/post/$(postID))
}
function existsPost(postID) {
return exists(/databases/$(database)/documents/post/$(postID))
}
match /post/{postID} {
allow create: if getPost('post_id_1').data != null
&& getPost('post_id_2').data != null
&& getPost('post_id_3').data != null
&& getPost('post_id_4').data != null
&& getPost('post_id_5').data != null
&& existsPost('post_id_6')
&& existsPost('post_id_7')
&& existsPost('post_id_8')
&& existsPost('post_id_9')
&& existsPost('post_id_10')
&& existsPost('post_id_11');
}
}
}
これだと書き込みエラーになる。どうやら単体で10回までというよりは、
get()
exists()
getAfter()
合計で10回までのようだ。
ルールシミュレータだと
異なるpathのドキュメントに対してget()
を11回呼び出しても成功となったのでまだ動作が不穏な感じではある 🤔
まとめ
今まで単体呼び出し3回、合計5回だったのが10回に緩和されたので、今までよりget()
exists()
getAfter()
の呼び出し回数に怯えることはなくなった。