0

I'm trying to prevent double voting in firebase. My idea was to make a vote object in firebase and then add a user_id boolean every time someone votes. So counterTips>votes>User_id1: true> UserId2: True.

These were my security rules :

{

  "rules": {
    ".read": true,
    ".write": true,
      "CounterTips": {
     "votes": {
                "$uid": {
                    ".write": "auth.uid != null && auth.uid === $uid"
                }
              }
            }
  }


}

This is the way my db is structured

CounterTips 

 user_id: "rI9m9GEkyKhopAhaDNC8GNWPS943"

 vote: 5, 

 votes: 
1) bbz9MLo1u7T7zxugmHA806nMof93: true

I'm trying to push current users id into votes object, but instead am just getting a static string that says user_id: true. How do I push an actual user_id to votes and prevent that user from voting again in the security rules?

     upvotePost(key, vote, user_id) {

if (this.state.user_id !=null )
{

CounterTipsref.child("votes/${this.state.user_id}").once("value",snapshot => {
    if (snapshot.exists()){
      const userData = snapshot.val();
      console.log("exists!", userData);
    }


});
}

 else{
alert(this.state.user_id);
let user_id= this.state.user_id;
let votes = { [user_id]: true};

vote++;
CounterTipsRef.child(key).update({ 'vote': vote, 'votes': votes }); 
}
}
if (this.state.user_id==null) {

this.props.history.push('/login');
}


  }
}
Leo Bogod
  • 369
  • 8
  • 28
  • my thought on this has always been: a boolean actually conveys 3 states (rather than 2), namely - `true`, `false`, and `null`. In other words, the property is the users `uid` and `true` for upvote, `false` for downvote, and non-existent (`null`) for no vote. – Ronnie Royston Sep 08 '18 at 01:30

1 Answers1

1

Your problem is that you're using this notation:

let votes = { user_id: true};

The user_id in here is seen as the name of the property, instead of the variable holding the name of the property. The quick fix is to use [] notation:

let votes = { };
votes[user_id] = true;
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • ok that works , so now how do i right security rule to prevent the user from voting twice? – Leo Bogod Sep 07 '18 at 16:26
  • The simplest way is to not keep a separate counter. If all you have is the collection of votes, and every user can only vote under their own UID, the votes are automatically unique. You can simply count the votes by downloading `votes` and counting them in the client. If you want to keep a separate counter, and ensure that updates to that are in line with folks adding/removing their UID, have a look at my answer here: https://stackoverflow.com/questions/37954217/is-the-way-the-firebase-database-quickstart-handles-counts-secure – Frank van Puffelen Sep 07 '18 at 17:45