8

ユーザーがアイテムを作成し、他のユーザーがそれらのアイテムを購読できるようにするアプリケーションを作成しています。ユーザーがアイテムを複数回サブスクライブできないようにするルールを作成するのに苦労しています。

これが私のデータ構造の例です(匿名化されているため、「OMITTED」値です):

{
    "OMITTED" : {
        "name" : "Second",
        "body" : "this is another",
        "userName" : "Some User",
        "userId" : "OMITTED",
        "created" : 1385602708464,
        "subscribers" : {
            "OMITTED" : {
                "userName" : "Some User",
                "userId" : "OMITTED"
            }
        }
    }
}

現在、私のFirebaseルールは次のとおりです。

{
  "rules": {
    ".read": true,
    ".write": "auth != null",
    "items": {
      "$item": {
        ".write": "!data.exists()",
        ".validate": "newData.hasChildren(['name', 'body', 'userId', 'userName']) && newData.child('userId').val() == auth.id",
        "subscribers": {
          "$sub": {
            ".validate": "newData.hasChildren(['userId', 'userName']) && newData.child('userId').val() != data.child('userId').val()"
          }
        }
      }
    }
  }
}

ユーザーが複数回購読できないようにするにはどうすればよいですか? subscribersに基づいて、リスト内でユーザーの重複を防ぐために必要なルールは何userIdですか?

4

1 に答える 1

5

セキュリティ ルールはレコードのリストを繰り返し処理して、特定のビットのデータを含むレコードを見つけることができないため、ここでの秘訣は、簡単にアクセスできる ID でレコードを保存することです。非正規化に関する優れた記事があり、この実践についていくつかの優れた洞察を提供しています。

この場合、ユース ケースが許せば、次のように ID を値としてレコードに格納するのではなく、ユーザーの ID によってレコードが格納されるように、単純にデータ構造を切り替えたい場合があります。

/users/user_id/items/item_id/subscribers/user_id/

実際、非正規化でわかるように、データの正確なサイズと後でどのように読み取るかによっては、さらに分割することでメリットが得られる場合もあります。

/users/user_id
/items/user_id/item_id
/subscribers/item_id/user_id

これらの形式のいずれかで、次のような方法で、重複を防ぎ、セキュリティをかなりうまくロックダウンできるようになりました。

{
   "users": {
      "$user_id": { ".write": "auth.id === $user_id" }
   },
   "subscribers": {
      "$subscriber_id": { ".write": "auth.id === $subscriber_id" }
   }
}
于 2013-11-29T17:52:12.370 に答える