【问题标题】:How to implement ondelete cascade in Firebase (Android)如何在 Firebase (Android) 中实现 ondelete 级联
【发布时间】:2017-04-09 22:32:43
【问题描述】:

我是 Firebase 的新手。我想在 Firebase 中实现 ondelete 级联。 这是我想要解决的问题 我有两个表“用户”和“组”。

{  "users":{
"user1":{
    "username":"john",
    "full_name":"John Vincent",
    "created_at":"9th Feb 2015",
    "groups":{
        "group1":true,
        "group3":true
    }
    "last_logins":...
},
"user2": ...,
"user3": ...
}"groups": {
 "group1"{
    "group_name":"Administrators",
    "group_description":"Users who can do anything!",
    "no_of_users":2,
    "members":{
        "user1":true,
        "user3":true
    }
  },
 "group2"{
    "group_name":"Moderators",
    "group_description":"Users who can only moderate!",
    "no_of_users":1,
    "members":{
        "user2":true
    }
  }
}
}

请原谅我上面的代码缩进。

现在,如果我从用户表中删除了 user1,那么应该如何使用 Firebase 从组表中自动删除它。

这可以使用 SQL 轻松完成,但我不知道如何在 Firebase 中执行此操作。在 Firebase 中执行此操作的一种方法是从用户中删除 user1,然后使 group1 和 group3 为空,然后在组表中使 user1 在 group1/member 下为空,但这需要 2-3 次调用。那么有没有其他最好的方法来做到这一点。 请帮帮我,我被困在这里了。

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    Firebase 数据库不知道其 JSON 树中的值之间的关系。在 SQL/关系术语中:它没有外键的概念。这意味着它也没有使用级联删除删除相关对象的选项。您需要分别删除每个值。

    但是您可以使用multi-location updates 将所有这些删除合并到一个调用中。如果您将null 写入用户的每个位置,则可以通过调用updateChildren() 将其全部删除:

    DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
    Map<String,Object updates = new HashMap<String,Object>();
    updates.put("users/user1", null);
    updates.put("groups/group1/members/user", null);
    // Do a deep-path update
    ref.updateChildren(updatedUserData, new Firebase.CompletionListener() {
       @Override
       public void onComplete(FirebaseError firebaseError, Firebase firebase) {
           if (firebaseError != null) {
               System.out.println("Error updating data: " + firebaseError.getMessage());
           }
       }
    })
    

    有了这个,你就可以写security rules validate 一个组的成员也必须存在于/users 节点下:

    {
      "rules": {
        "groups":
          "$groupid": {
            "users": {
              "$uid": {
                ".validate": "newData.parent().parent().parent().parent().child('users').hasChild($uid)"
              }
            }
          }
        }
      }
    }
    

    如果您将多个.parent() 调用读取为newRoot(不幸的是不存在),验证规则会更容易理解。所以在伪代码中是:

    newRoot.child('users').hasChild($uid)
    

    换句话说:如果 UID 也存在于/users 下,它只能是组的成员。

    【讨论】:

    • 我想要的完美解决方案。谢谢@Frank van Puffelen
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    相关资源
    最近更新 更多