Scandinave
Scandinave

Reputation: 1438

How to secure my Firebase App build with EmberFire

I scratch my head for that Firebase security works as i want. My app is build with Ember and so with EmberFire. So structure is determine by EmberFire.

My database structure is as follow :

conversations : {
    $conversation_id {
        messages {
            //message data
        }
        users {
            $user_id1 :true
            $user_id2 :true
        }
    }
}

What i want is that only users that are part of a conversation can see and write message in this conversation. I tried this rule without success :

"conversations" : {
    ".indexOn" : "notify",
    ".read" : "auth !== null && root.child('users').hasChild(auth.uid)", 
    ".write": "auth !== null && root.child('users').hasChild(auth.uid)"
}

It seems that auth.uid can't be passed to hasChild. I also tried the following, because my conversation id is the join of users id that participate to the conversation :

"conversations" : {
   ".indexOn" : "notify",
   "$conversation" : {
       ".read" : "auth !== null && ($conversation.beginsWith(auth.uid) || $conversation.endsWith(auth.uid))", 
       ".write": "auth !== null && ($conversation.beginsWith(auth.uid) || $conversation.endsWith(auth.uid))"
   }
}

With this rule, no one can see conversation because the "conversations" node does not have .read rule. But if i adds ".read : true" to the "conversations" node, due to top-bottom rules in Firebase, all users can see all conversations.

Edit : The second rule has the same problem that the first. beginsWith() expects a string argument. And auth.uid can't be used Any idea to solve my problem?

Edit : Add auth !== null before the rule,makes that the error beginsWith() expects a string argument get out. But both rules still does not work.

Upvotes: 0

Views: 118

Answers (1)

msdedwards
msdedwards

Reputation: 509

The problem with your first try was that you were using root, but should have been using $conversation. Root is a rule snapshot that references root of the firebase, whereas $conversation is a variable that holds the id of the conversation you are trying to read/write.

"conversations" : {
       ".indexOn" : "notify",
       "$conversation" : {
           ".read" : "auth !== null && root.child('conversations/'+$conversation+'/users').hasChild(auth.uid)", 
           ".write": "auth !== null && root.child('conversations/'+$conversation+'/users').hasChild(auth.uid)"
       }
    }

Upvotes: 4

Related Questions