web-dev-qa-db-ja.com

マップ値に基づくFirestoreセキュリティルール

ユーザーのメールアドレスに基づいて、ユーザーがドキュメント自体のドキュメントを読むことを許可されているかどうかを保存したいと思います。複数のユーザーが同じドキュメントにアクセスできる必要があります。

ドキュメント によると、Firestoreは配列メンバーのクエリを許可していません。そのため、ユーザーの電子メールアドレスを、電子メールアドレスをキーとしてString-Boolマップに格納しています。

次の例では、基本的な文字列ではすでに機能していないため、マップキーとして電子メールを使用していません。

データベース構造は次のようになります。

lists
  list_1
    id: String
    name: String
    owner: E-Mail
    type: String
    shared:
      test: true

すべてのセキュリティルールは次のとおりです。

service cloud.firestore {
  match /databases/{database}/documents {
    match /lists/{listId=**} {
        allow read: if resource.data.shared.test == true
    }
  }
}

編集:match /lists/{listId}の代わりにmatch /lists/{listId=**}を使用した場合も機能しません

私の理解では、このセキュリティルールでは、マップshared[test]の値がtrueの場合、すべてのユーザーに読み取りアクセスを許可する必要があります。

完全を期すために:これは私が使用しているクエリです(AndroidのKotlin):

collection.whereEqualTo("shared.test", true).get()
        .addOnCompleteListener(activity, { task ->
            if (task.isSuccessful) {
                Log.i("FIRESTORE", "Query was successful")
            } else {
                Log.e("FIRESTORE", "Failed to query existing from Firestore. Error ${task.exception}")
            }
        })

セキュリティルールからマップ値にアクセスできないと思います。では、私の問題に対する代替の解決策は何でしょうか?

Firestoreルールリファレンス マップはそのようにアクセスできると書かれていますresource.data.property == 'property'それで、私は何が間違っているのですか?

13
Marcel Bochtler

編集:この問題は今すぐ修正する必要があります。それでも表示される場合(およびルールエバリュエーターのバグであると確信している場合)は、コメントでお知らせください。

私はあなたが直面している問題についてここで何人かの人々と話をしました、そしてそれはセキュリティルール自体の問題であるように見えます。基本的に、問題は、実行していることのように、クエリ内のネストされたフィールドの評価に固有のようです。

したがって、基本的に、実行していることは正常に機能するはずであり、このクエリを機能させるには、Firestoreチームからの更新を待つ必要があります。それが起こったとき、私はこの答えを更新することを忘れないようにします。申し訳ありませんが、それについて!

10
Todd Kerpelman

(オプションの)ネストされたプロパティがある場合は常に、その値をチェックし続ける前に、プロパティが存在することを確認する必要があります。

allow read: if role in request.auth.token && request.auth.token[role] == true

あなたの場合:

allow read: if test in resource.data.shared && resource.data.shared.test == true

、管理者以外のユーザーでは管理者フィールドが定義されておらず、Firestoreルールがクラッシュし、他の可能な一致をチェックし続けないことに気付くまで、私は長い間役割に苦労していました。

Token.adminを持たないユーザーの場合、他に一致するものがあるかどうかに関係なく、これは常にcrashになります。

function userHasRole(role) {
  return isSignedIn() && request.auth.token[role] == true
}
0
Gerardlamo