0

I have a polling app where each pole has the following structure-

topic: Topic
questions 
{
  Q1
  {
    name: "q1"
    type: "Single Choice"
    options: ["Yes", "No"]
  }
  Q2
  {
    name: "Q2"
    type: "MCQ"
    options: ["A", "B", "C"]
  }
  Q3
  {
    name: "Q3"
    type: "LongAnswer"
    options: null
  }
}

The poll results document looks like this-

{
  "Q2": {
    "A": 3,
    "C": 6,
    "B": 3
  },
  "Q3": {
    "Responses": [
      "This is my response."
    ]
  },
  "Q1": {
    "No": 2,
    "Yes": 4
  }
}

I need to write down a security rule that ensures that a user can make an increment of only 1 in the values and can't change more than one values if the question is of "Single Choice" type. But, the number of questions or options are not known beforehand and the security rules don't allow loops. What should I do?

James
  • 75
  • 7

2 Answers2

1

This is not going to be possible unless you know the structure of each question ahead of time. You should instead send the vote through a backend that lets you be more flexible about what you check, and only write updates that meet your requirements.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
1

As you discovered you can't do anything "loop like" in security rules.

So you'll need to change your data model to allow the use-case. Since you say that a user must only be able to do something once, that means you should use the UID as the key:

responses: {
  $uid: "thing they voted on"
}

I'd then recommend using Cloud Functions to then tally the results. It may be possible to enforce the restriction using ServerValue.increment() and security rules on the above data structure, but they will end up being rather complex.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Could you tell me about ServerValue.increment() idea of yours? I didn't find it in the firebase rules documentation. – James Aug 08 '20 at 00:54
  • Sorry, but as said: implementing that is going to be rather complex, and beyond what I'm interested in writing from scratch here. If you want to take that approach, I recommend studying similar questions and trying it. For example, here's something similar in Realtime Database rules: https://stackoverflow.com/questions/37954217/is-the-way-the-firebase-database-quickstart-handles-counts-secure – Frank van Puffelen Aug 08 '20 at 01:53