0

I am having some issues with Firebase security rules. I want any user to be able to create an account using my iOS app at the same time once he or she establishes the account I want to have two nodes one is private, and one is public. I want the public to be accessed by anyone, including the user its self, but the user that created the account only accesses the private node. I have tried a lot of things, but none of my work seems to work. I want to fetch all the public node values by just having a link without knowing the uid of each user

1- Anyone can create an account 2- Only the user can access his own private node 3- A link where I can fetch all of the user's public node only

Thank you!!!!

for example, I would like to fetch all the users https://id.firebaseio.com/Ireland.json

This is my database

Here is some of my work

{
  "rules": {
    "Ireland": {
      "users": {
        "$uid": {
          "private": {
            ".read": "auth != null && auth.uid == $uid",
            ".write": "auth != null && auth.uid == $uid",
          },
          "public": {
            ".read": true,
            ".write": "auth != null && auth.uid == $uid",
          },
        },
      },
    },
  },
}

here is my swift code, but every time I try to create an account it says permission denied

guard let uid = result?.user.uid else { return }

let privateValues = ["email": email, "username": username, "password": password, "profileImageUrl": profileImageUrl, "country": "Ireland"]
let publicValues = ["username": username, "profileImageUrl": profileImageUrl]

let values = [uid: ["private": privateValues, "public": publicValues]]

                    Database.database().reference().child("Ireland").child("users").updateChildValues(values, withCompletionBlock: { (error, reference) in
if let error = error {
print("Failed to save user info to database: ", error)
self.signUpButton.wiggle()
return
}
Mutaeb Alqahtani
  • 354
  • 4
  • 13

1 Answers1

1

Firebase security rules cannot be used to filter data. All they do is check if a certain read operation is allow, without checking each individual node.

So if you attach a listener to /Ireland, the server checks if the current user has read permission to /Ireland. Since nobody has permission on that level, the read operation is rejected.

This is also known as 'rules are not filters' in both the documentation and previous questions.

Last year Firebase added support for validating queries in security rules, so that for example you can allow queries that also filter by a ownerUID type property. See the documentation on query based rules for more on that.

But that won't work for your use-case either, since read operations always return full nodes. Which brings us back to the fact that security rules can't be used to filter data.

You will have to separate the public and private data into two separate top-level nodes: private and public. This is one of the many reasons the Firebase documentation recommends keeping your data structure flat.

Also see:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Now I understand and thank you for your time. But one thing since I have the write permissions set to "auth != null && auth.uid == $uid" I am not able to create new yours with this. Is there any way around it? – Mutaeb Alqahtani Jul 30 '19 at 05:01
  • As long as you put that rule at the correct level, it should work. If you continue to have problems, open a new question for this new problem. – Frank van Puffelen Jul 30 '19 at 05:17