Skip to content

Instantly share code, notes, and snippets.

@krawaller
Created May 9, 2017 05:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krawaller/4b45fa8a1a27f570b63acd6f39c2eb2f to your computer and use it in GitHub Desktop.
Save krawaller/4b45fa8a1a27f570b63acd6f39c2eb2f to your computer and use it in GitHub Desktop.
Enforcing Firebase relation validity

Say we have a database of users and roles, where each user belongs to a role. Using the denormalized Firebase approach I might store that like this:

{
  "users": {
    "abc123": {
      "name": "Joe",
      "role": "kkk333"
    },
    // lots more users
  },
  "roles": {
    "kkk333": {
      "name": "admin",
      "users": {
        "abc123": true,
        // lots more refs to users
      }
    }
  }
}

I expected to be able to use rules to validate the relations, something like this:

{
  "users": {
    "$userid": {
      "role": {
        ".validate": "root.child('roles/'+newData.val()+'/users/'+$userid).val() === true"
      }
    }
  },
  "groups": {
    "$groupid": {
      "users": {
        "$userid": {
          ".validate": "newData.val() === true && root.child('users/'+$userid+'/role').val() === $groupid"
        }
      }
    }
  }
}

And then do changes using the .update method, editing both places at once. Here's adding a new user:

ref.update({
  'users/newuserkey123': {
    name: 'David',
    role: 'oldrolekey456'
  },
  'roles/oldrolekey456/users/newuserkey123': true
});

But, unless I'm mistaken, this will never work, because rule validation is applied to each prop in the update object separately.

So, my question is:

  • Is it correct that I cannot use .update in this way, or did I simply screw something up?
  • If the above assumption is correct, what is the correct way to enforce good relations? Using real-time database triggers?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment