0

Is there any way to validate newData using Firebase security rules as follows?

"Event": {
 "$eventId": {
  "Outcome": {
   ".validate": "
     newData.parent().parent().parent().child('Users/'+$userId+'/Events/'+$eventId+'/Opinion').exists()
   "

What I'd like to achieve is to make sure that a multi-location update happens atomically.

Use-case: How to make sure that a single write contains the outcome for the event and an opinion for each user

At the moment, '$userId' cannot be added to the rule, so the above rule is invalid. I want to have something like '*' instead of '$userId' to make sure that the 'Outcome' of the 'Event' can be updated, only if ALL the 'opinion' fields under all 'Users' also get updated. Is this possible?

UPDATE: more details: the rule for updating the user's data looks like this:

"Users": {
     "$userId": {
      "Events": {
       "$eventId": {
        ".validate": "
          newData.parent().parent().parent().parent().child('Event/'+$eventId+'/Outcome').exists()
        "
}}}}

This works fine, because the only wildcard needed is the $eventId which is already defined before the ".validate". However, under the "Event", there is no "$userId", so the "$userId" wildcard cannot be used there.

This is how I do my multi-location update:

var multiData = {}

multiData['Event/' + $scope.eventId + '/Outcome'] = $scope.eventOutcome;

for (var u=0; u<$scope.allUsers.length; u++) {
      var curUser = allUsers[u];
      multiData['Users/' + curUser.id + '/Events' + $scope.eventId + '/Opinion'] = $scope.usrOpinions[u];
}
ref.update(multiData, function(error) {
      if(error) {...}
      else {...}
});
towi_parallelism
  • 1,421
  • 1
  • 16
  • 38
  • Yes. But the exact details depend on your exact use-case, which is somewhat underspecified in your question at the moment. For a quite advanced example of validating both the new data and the existing data, see this answer I gave a while ago: http://stackoverflow.com/questions/37954217/is-the-way-the-firebase-database-quickstart-handles-counts-secure/37956590#37956590 – Frank van Puffelen Oct 05 '16 at 13:56
  • @FrankvanPuffelen, thanks for you answer, but even that example doesn't cover my case. I have updated my question. The atomic update rule could be applied to the User's update, as described above (to be synced with the Event's update), but the corresponding rule cannot be used under the 'Event', because '$userId' doesn't exist under 'Event'. – towi_parallelism Oct 05 '16 at 15:42
  • Share the existing JSON that is affect by the operation you want to validate, the location you're updating, the JSON you're posting, the uid of the active user. Without those it's hard to parse (at least for me, maybe someone else does better). [MCVE](http://stackoverflow.com/help/mcve) – Frank van Puffelen Oct 05 '16 at 15:51
  • @FrankvanPuffelen, I have updated the question with the JS code to update the locations. – towi_parallelism Oct 05 '16 at 16:36
  • OK. I now realize this is very much a [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Let's see if I understand the use-case: your app records the opinions of users for an event. And now you want to validate that a single write contains the outcome for the event *and* an opinion for each user? If that is indeed the use-case, put it in your question. If your use-case is different, put the correct use-case in your question. – Frank van Puffelen Oct 05 '16 at 17:02
  • @FrankvanPuffelen, yes, that's right. Updated the question to make it clearer. – towi_parallelism Oct 05 '16 at 17:52

0 Answers0