Firebase数据库规则:如何防止某个子项被删除(又称为NOTNULL)?

Firebase数据库规则:如何防止某个子项被删除(又称为NOTNULL)?,firebase,firebase-realtime-database,firebase-security,Firebase,Firebase Realtime Database,Firebase Security,我试图在firebase中定义一个模式,以防止某些子属性像SQL中的NOTNULL约束一样为null 架构应如下所示: Property | allow null | type ---------+------------+-------- name | false | string phone | false | string alias | true | string birthday | true | number (time

我试图在firebase中定义一个模式,以防止某些子属性像SQL中的NOTNULL约束一样为null

架构应如下所示:

Property | allow null | type
---------+------------+--------
name     | false      | string
phone    | false      | string
alias    | true       | string
birthday | true       | number (timestamp) 
{
  "rules": {
    "contacts": {
      "$user": {
        "$contact": {
          ".read": "auth.uid == $user",
          ".write": "auth.uid == $user && newData.hasChildren(['name', 'phone'])",
          "name": {
            ".validate": "newData.isString()"
          },
          "phone": {
            ".validate": "newData.isString()"
          },
          "alias": {
            ".validate": "newData.isString()"
          },
          "birthday": {
            ".validate": "newData.isNumber()"
          },
          "$other": {
            ".validate": "false"
          }
        }
      }
    }
  }
}
此外,只有用户自己才能读写自己的联系人

当前数据库中有一些虚拟数据:

{
  "contacts" : {
    "user1" : {
      "contact1" : {
        "alias" : "Bobby",
        "name" : "Bob",
        "phone" : "12312324"
      }
    }
  }
}
我提出的解决方案如下所示:

Property | allow null | type
---------+------------+--------
name     | false      | string
phone    | false      | string
alias    | true       | string
birthday | true       | number (timestamp) 
{
  "rules": {
    "contacts": {
      "$user": {
        "$contact": {
          ".read": "auth.uid == $user",
          ".write": "auth.uid == $user && newData.hasChildren(['name', 'phone'])",
          "name": {
            ".validate": "newData.isString()"
          },
          "phone": {
            ".validate": "newData.isString()"
          },
          "alias": {
            ".validate": "newData.isString()"
          },
          "birthday": {
            ".validate": "newData.isNumber()"
          },
          "$other": {
            ".validate": "false"
          }
        }
      }
    }
  }
}
这种方法的问题是,每当我想修补某个值(例如别名)时,我必须提供不因newData.hasChildren['name','phone']规则而更改的NOTNULL属性

虽然我可以访问我的应用程序中的整个对象,但这是一个恼人的不便

有没有更好的方法来解决这个问题

这种方法的问题是,每当我想修补某个值(例如别名)时,我必须提供不因newData.hasChildren['name','phone']规则而更改的NOTNULL属性

您似乎误解了规则中新数据的含义。从:

与允许写入时将产生的数据相对应的RuleDataSnapshot


因此,如果只将一个属性写入已包含所有属性的位置,newData变量将包含所有属性:未指定属性的现有值,以及您正在编写的属性的新值。

Firebase没有模式,因此通常最好不要在NoSQL数据库上强制使用SQL概念-思考并设计NoSQL的结构!例如试图防止某些子属性为null。为什么?如果没有数据会发生什么?如果你想确保它有数据,什么数据?Firebase不允许空字符串,因此这意味着您需要有一些内容作为子值占位符。在NoSQL的情况下,缺少子节点通常比占位符好。依法处理,;如果phoneChildNode.exists然后让phoneVar=未提供电话那么为什么模拟器显示使用虚拟数据拒绝写入?因为您正在对整个用户模拟一个集合操作。这将替换整个联系人,包括姓名和电话属性。要模拟更新,请将值写入contacts/user1/contact1/alias.Thank,这样可以消除很多困惑和挫折。