1
votes

I have for the last two days been struggling with the rules for my Firebase project. I have my data structure like this:

            Users{
            wildCardID{
            username:John
            gender:male
            StripeInfo{
accountID:myaccountid
secretpublishablekey:thekey
someothersecretinfo:secretinfo

           }
            pushToken{
            tokenid:mytokenid
           }
          }
         }

So my problem is, I can't get my rules right in terms of sign up. During signup I simply create a new autoByID in Users, but if I set the ".read":true inside Users, everyone can simply see the secretpublishablekey and someothersecretinfo inside the StripeInfo child. How would I avoid this? I have tried to set ".read":"auth === $uid(in this case, wildCardID)", but due to the structure of the Firebase rules (and as far as I know) once a permission has been granted, it can not be un-granted again. How would I solve this problem of mine?

I want the user to register a user, I want the username to be ".read":true, due to the fact that you have to check if the username is in use during signup. However, to make purchases inside my app, the user needs to retrieve the other users accountID inside the StripeInfo child, so this would be set to ".read":"auth !== null". But the remaining data (secretpublishablekey and someothersecretinfo) would be set to ".read":"auth.uid === $uid".

This problem also occurs when I try to implement the .write. I simply just want the user to edit their own personal details, or if there's a new registration - I want the user to be able to create a new child inside Users. How would I do so without messing up? I've searched so many places now without getting any information on this. Is it impossible?

If I set the .write to true in users, it simply gives the permission for other users to edit other user details as well, and I really want to prevent this, and solve this as quick as possible. Can someone please help me?

1
Is there no possible way to fix this?askaale

1 Answers

1
votes

Caveat: I haven't done this before but I've just finished checking out the video on rules.

Create a metadata underneath your User structure so that you store hidden data in that area. If you need to break out some of the metadata for public use just change that key or better yet put the public data under the User object and totally restrict read/write access to the metadata.

Revised data structure should be something along these lines:

/Users/$uid (wildcard) / metadata / hiddenKeyForValue

Then in your rules create something like:

{
"rules": {
    "Users": {
     "$uid": {
       "publicMetadata": {
              ".read" : "auth !== null",
              ".write" : "auth !== null" 
           }  
       "metadata" : {
              ".read" :  $uid === auth.uid ,
              ".write" : $uid === auth.uid 
       }
     } 
    }
  }
}

So basically, if you put the hidden data under a single node then you can write one set of rules too manage that .. Otherwise you have to write a lot more rules. I found this part of the guide useful along with the simulator. The section on securing data has details on the server variables along with more detailed samples.

Also for more on using validation, which is more restrictive than write/read rules see the following video. Or in a nutshell you can view this image:

complex-validation

You can apply rules to areas set aside for registered users (as opposed to anonymous users) by reviewing the registered users list for the current authorized uid.

root-child-validation