Firestore规则更新复杂文档中的一个字段

时间:2019-03-17 10:14:33

标签: firebase google-cloud-firestore firebase-security-rules

去年我创建了一个Angular / Firebase应用程序,并且开始创建一个类似的应用程序,但是这次使用Firestore,因为我已经阅读了它的“改进版本”(我知道它的工作方式不同,请阅读更多内容)所以What's the difference between Cloud Firestore and the Firebase Realtime Database?)。

看到它仅适用于集合/文档而不适用于字段(触发器和规则)后,我有点不情愿。我一直在寻找带有规则的数据结构的更复杂的示例,但是什么也没看到。

就我而言,我具有这种结构(我从firebase rdb应用程序中获取了它,但我认为它适合用于Firestore):

users (=collection)
  |__ $id (=document)
       |__ username
       |__ country
       |__ language
       |__ gender
       |__ score
       |__ online
       |__ ...

取决于他们是应用程序的哪种状态,用户可以一次更新多个字段(用户名,国家/地区,语言,性别...),也可以仅更新一个字段(例如得分)。他们也无法更新某些字段(例如,在线)。

使用RDB规则,我可以轻松地写出这样的内容:

// USERS
"users": {
  // USERS > $UID
    "$uid": {
    ".read": "$uid === auth.uid",
    // USERS > $UID > USERNAME
    "username":{
      ".write": "$uid === auth.uid &&
          !root.child('usernames/'+newData.val().toUpperCase()).exists() &&
          data.val() === ''",
      ".validate": "newData.isString() && newData.val().matches(/^.{3,15}$/)"
    },
    // USERS > $UID > COUNTRY
    "country": {
      ".write": "$uid === auth.uid && data.val() === ''",
      ".validate": "newData.isString() && newData.val().length === 2"
    },
    // USERS > $UID > LANGUAGE 
    "language": {
      ".write": "$uid === auth.uid",
      ".validate": "newData.isString() && newData.val().length === 2"
    },
    // USERS > $UID > ONLINE
    "online": {
      ".write": "$uid === auth.uid",
      ".validate": "newData.isBoolean()"
    },
    // USERS > $UID > GENDER
    "gender": {
      ".write": "$uid === auth.uid && data.val() === ''",
      ".validate": "newData.isString() && (newData.val() === '' || newData.val() === 'man'
        || newData.val() === 'woman')"
    }
  }
}

但是使用Firestore看起来确实要复杂得多。我开始写东西(错误的atm):

// USERS > $UID
match /users/{userId} {
  allow read: if request.auth.uid == userId;
  allow update: if request.auth.uid == userId 
  // USERS > $UID > USERNAME
    && resource.data.username == ''
    && request.resource.data.username.matches("/^.{3,15}$/")
    && request.resource.data.username is string
    && !exists(/databases/$(database)/documents/usernames/$(request.resource.data))
  // USERS > $UID > COUNTRY
    && request.resource.data.country is string
    && request.resource.data.country.size() == 2
    && resource.data.country == ''
  // USERS > $UID > LANGUAGE
    && request.resource.data.language is string
    && request.resource.data.language.size() == 2
  // USERS > $UID > GENDER
    && resource.data.gender == ''
    && request.resource.data.gender is string
    && request.resource.data.gender in ["man", "woman"];
}

首先,我的结构好吗? 有规则的复杂结构的好例子吗?

(很少有类似的主题:Firestore rules for document fieldFirestore update only one field

0 个答案:

没有答案