mercredi 24 février 2016

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" : "root.child('users').hasChild(auth.uid)", 
    ".write": "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" : "$conversation.beginsWith(auth.uid) || $conversation.endsWith(auth.uid)", 
       ".write": "$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?




2 commentaires:

  1. Ce commentaire a été supprimé par l'auteur.

    RépondreSupprimer
  2. When you do root.child() you are starting at '/' base of entire firebase tree. So if you are inside /conversations and use "root.child('users') you are not asking for "/conversations/users" you are asking for "/users" which is in root of database and not nested inside conversations. You would have to ask for root.child('conversations/'+$conversation_id+'/users/'+auth.uid).exists(). exists() is how you can test for auth.uid without having to use .hasChild().

    RépondreSupprimer