组的 Firebase 数据库规则

Firebase Database Rules for groups

我有这个 Firebase 数据库,如果需要可以更改它:

该数据库的 JSON 是:

{
  "groups": {
    "1": {
      "name": "G1",

      "points": {
        "1": {
            "name": "p1"
        }
      },
      "visits": {
        "1": {
            "name": "v1"
        }
      },
      "areas": {
        "1": {
            "name": "a1"
        }
      },
      "waypoints": {
        "1": {
            "name": "w1"
        }
      },
      "interests": {
        "1": {
            "name": "i1"
        }
      }
    },
    "2": {
      "name": "G2",

      "points": {
        "2": {
            "name": "p2"
        }
      },
      "visits": {
        "2": {
            "name": "v2"
        }
      },
      "areas": {
        "2": {
            "name": "a2"
        }
      },
      "waypoints": {
        "2": {
            "name": "w2"
        }
      },
      "interests": {
        "2": {
            "name": "i2"
        }
      }
    }
  },
  "users": {
    "qdRw1khg1ZO1s52YioYCdM4WrD02": {
      "firstName": "AAAA",
      "lastName": "BBB",
      "email": "sdf@sdfs.com"     
    },
    "h3KYDXkPQrY246w6Y6NXIanVoNS2": {
      "firstName": "FF",
      "lastName": "RR",
      "email": "wwf@jjuzhz.com"
    }
  },
  "userGroups": {
    "qdRw1khg1ZO1s52YioYCdM4WrD02": {
      "1": "admin",
      "2": "readwrite"
    },
    "h3KYDXkPQrY246w6Y6NXIanVoNS2": {
      "1": "admin",
      "2": "readonly"     
    }
  }
}

我想定义规则来完成以下任务:

我有:

"groups": {          
  "$groupId": {
    ".read": "root.child('userGroups').child(auth.uid).child($groupId).exists()",
    ".write": "! root.child('userGroups').child(auth.uid).child($groupId).exists() || 
                          (data.parent().val() === 'points' && root.child('userGroups').child(auth.uid).child($groupId).val() != 'readonly') ||
                        (data.parent().val() === 'visits' && root.child('userGroups').child(auth.uid).child($groupId).val() === 'readonly') ||
                        (data.parent().val() != 'points' && data.parent().val() != 'visits' && root.child('userGroups').child(auth.uid).child($groupId).val() === 'admin')"
  }
},
"users": {
  "$userId": {
    ".read": "auth != null",
    ".write": "auth != null && 
              $userId === auth.uid && 
              newData.val() != null"
  }
},
"userGroups": {
  "$userId": {
    ".read": "auth != null",
    ".write": "auth != null && 
               data.child(auth.uid).val() === 'admin' && 
               newData.val() != null"          
  }
}

但这行不通,因为

data.parent().val()

不 return parent 的名称字符串。所以我做不到

data.parent().val() != 'points'

如何解决这个问题?问题是根据指定的规则将数据写入组。

如果您尝试 "points" 和 "visits" 级别的嵌套规则会怎样:

"groups": {          
  "$groupId": {
    ".read": "root.child('userGroups').child(auth.uid).child($groupId).exists()",
    ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() == 'admin'",
    "points": {
      ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() != 'readonly'"
    },
    "visits": {
      ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() != 'readonly'"
    }
  }
},
"users": {
  "$userId": {
    ".read": "auth != null",
    ".write": "auth != null && 
              $userId === auth.uid && 
              newData.val() != null"
  }
},
"userGroups": {
  "$userId": {
    ".read": "auth != null",
    ".write": "auth != null && 
               data.child(auth.uid).val() === 'admin' && 
               newData.val() != null"          
  }
}

这里是 Firebaser。希望这个答案会随着我的进行而更新。

我的第一步是将特定子节点的规则移动到该特定子节点中。这消除了您一直遇到的 parent() 问题。第一次迭代是:

  "groups": {          
    "$groupId": {
      ".read": "root.child('userGroups').child(auth.uid).child($groupId).exists()",
      "points": {
        ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() !== 'readonly'"
      }
    }
  },

这允许用户 h3KYDXkPQrY246w6Y6NXIanVoNS2 写入 /groups/1/points(用户是管理员),但不能写入 /groups/2/points(用户只有只读访问权限)。

下一步是使规则更通用。为此,我引入了一个 $child 变量,它匹配组下的任何节点:

  "groups": {          
    "$groupId": {
      ".read": "root.child('userGroups').child(auth.uid).child($groupId).exists()",
      "$child": {
        ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() !== 'readonly'
                   || ($child !== 'points' && $child !== 'visits')"
      }
    }

这允许用户 h3KYDXkPQrY246w6Y6NXIanVoNS2 写入 /groups/2/name(任何组成员都可以写入),但不能写入 /groups/2/points(用户只有只读访问权限)。

更新:显然我颠倒了你上面的逻辑,所以这是我的最终看法:

  "groups": {          
    "$groupId": {
      ".read": "root.child('userGroups').child(auth.uid).child($groupId).exists()",
      ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() == 'admin'",
      "$child": {
        ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() === 'readwrite'
                   && ($child !== 'points' || $child !== 'visits')"
      }
    }

与此用户 h3KYDXkPQrY246w6Y6NXIanVoNS2:

  • 可以 写信给 /groups/1/name 因为他们是组 1
  • 的管理员
  • 可以 写信给 /groups/2/points 因为他们是组 1
  • 的管理员
  • 无法 写入 /groups/2/name 因为他们不是组 2
  • 的管理员
  • 可以 写入 /groups/2/points 因为他们是组 2
  • 的读写成员