質問: Cloud Firestoreのセキュリティルールを以下のように設定しています。 ``` service cloud.firestore { match /databases/{database}/documents { match /collectionA/{someID} { function checkA() { return get(/databases/$(database)/documents/collectionA/$(someID)/users/$(request.auth.uid)).data.deleteFlag != true } function checkB() { return get(/databases/$(database)/documents/collectionB/$(request.auth.uid)/companies/$(someID)).data.deleteFlag != true } allow read, write: if checkA() || checkB() } } } ``` データベースは以下の画像のような構成です。 ![Database](https://i.stack.imgur.com/ty3Yh.jpg) シミュレータを以下のように設定して、実行しました。 ``` シミュレーションタイプ : get 場所 : collectionA/companyA プロバイダ : password Firebase UID : aAzUlfztdYdEIXT3Tva73kCiuy93 ``` 関数checkA()はfalse、関数checkB()はtrueのはずなので、 アクセスは許可されることを期待していたのですが、「シミュレーションによるデータアクセスは許可されませんでした」と表示されました。 なお、関数を単体で呼ぶと、想定通り関数checkA()はfalseを、関数checkB()はtrueが返ってきました。 関数化したのがいけないのかと思い、allow read, write:のところに直接条件を書いても上記同様アクセスが許可されませんでした。 また、試しに、関数checkB()を、以下のようなtrueを返す別の条件式に変えて試してみたところ、アクセスは許可されたので、OR指定ができないというわけでもないのかなと思っています。 ``` function checkB() { return request.auth.uid != null } ``` どこが間違っているのかわかる方いらっしゃればご指摘いただけないでしょうか。 よろしくお願いいたします。
回答: シミュレータは稀に正しく動かないことがあるという情報があったので、念のため実際にクエリを投げて検証してみたところ、意図していた結果が得られたので、単純にシミュレータのバグかもしれないと考えていたのですが、Developer Platform Support に問い合わせをしたところ、以下のような回答をいただきましたのでご参考までに・・・。 > > get関数は、存在しないオブジェクトに対して値を取得しようとするとエラーとなる。 > > 条件判定過程でエラーが発生すると、セキュリティルール上はセキュリティルールを適用しない。 > > > 「各コレクションに存在するユーザデータに紐づくdeleteFlagのいずれかがFalseであった時に、セキュリティルールを適用するようにしたい」という要望について、セキュリティルールの仕様として、現状、存在しないオブジェクトについて細かい制御をする機能がないので難しい。 > > 回避策としては、collectionA、collectionBのそれぞれにUIDのデータが存在するようにデータを保持した上で、上記ルールを適用する。 > > >