3
votes

I have the following basic security rules below (anyone can read posts in the public database, and can read/write their own info to their account).

I want to place a Database Rule that will allow a specific UID (Example: cvFcflWuO3XCU8OtRoEkW9p2cXw1) read/write access to all information under /users/ , a wildcard rule for that specific UID that allows access to ALL subdirectories under /users/

{
  "rules": {
    "public":
    {
    ".read": true,
    ".write": false

    },
    "users": {
  "$uid": 
  {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

Doing a simple edit like the example below does not work.

".write": "'cvFcflWuO3XCU8OtRoEkW9p2cXw1' === auth.uid",
2
If you place that rule directly under "users": { it should work. If not, can you show the complete rules and the accompanying code that don't work together?Frank van Puffelen
Thanks for the confirmation that my code was correct. I tried it again and now it works fine. (I assume I mistyped something somewhere.)user1508405

2 Answers

0
votes

I tried my solution again and it worked fine.

Here is just a rules reference for anyone looking to do what I did. (This only gives read access, but you can just add another line for write.)

{
  "rules": {
    "public":
    {
    ".read": true,
    ".write": false

    },
	"users": {
    ".read": "'cvFcflWuO3XCU8OtRoEkW9p2cXw1' === auth.uid",
  "$uid": 
  {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}
0
votes

As per the documentation, the recommended approach is something like this:

{
  "rules": {
    "public_resource": {
      ".read": true,
      ".write": true
    },
    "some_resource": {
      ".read": "auth.uid === 'my-service-worker'",
      ".write": false
    },
    "another_resource": {
      ".read": "auth.uid === 'my-service-worker'",
      ".write": "auth.uid === 'my-service-worker'"
    }
  }
}

Then, on your server, when you initialize the FirebaseApp object, use the databaseAuthVariableOverride parameter to override the auth object used by your database rules. In this custom auth object, set the uid field to the identifier you used to represent your service in your Security Rules.

// Fetch the service account key JSON file contents
FileInputStream serviceAccount = new FileInputStream("path/to/serviceAccountCredentials.json");

// Initialize the app with a custom auth variable, limiting the server's access
Map<String, Object> auth = new HashMap<String, Object>();
auth.put("uid", "my-service-worker");

FirebaseOptions options = new FirebaseOptions.Builder()
    .setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
    .setDatabaseUrl("https://databaseName.firebaseio.com")
    .setDatabaseAuthVariableOverride(auth)
    .build();
FirebaseApp.initializeApp(options);

// The app only has access as defined in the Security Rules
DatabaseReference ref = FirebaseDatabase
    .getInstance()
    .getReference("/some_resource");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        String res = dataSnapshot.getValue();
        System.out.println(res);
    }
});