1

I'm working on a contact-app for android with firebase and I want to read values (here: the users' profile) from a user in my database that matches a specified email.

I tried to design the query like shown in this answer: https://stackoverflow.com/a/39025129/8739722 but the problem is that I don't know how to apply this to my database-structure since I have another child (profile) in my user-structure.

My Nodes look like this:

examplary-users-nodes

My Rules look like this:

{
"rules": {
    "users": {
      "$uid": {
        "profile": {
          ".read": "auth.uid != null",
          ".write": "auth.uid == $uid",
        },
        //...
    },
}

I tried to query like this:

String email = "email_address_1";
Query q_1 = ref.child("users").child("profile").orderByChild("email").equalTo(email);

...resulting in a 'permission denied' error.

I also considered following queries but they have invalid syntax or try to perform multiple orderByChild-calls which is not allowed:

String email = "email_address_1";
Query q_2 = ref.child("users").orderByChild("profile").child("email").equalTo(email);
Query q_3 = ref.child("users").orderByChild("profile").orderByChild("email").equalTo(email);

How can I get the profile-information of the user with the matching email?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

1 Answers1

0

Firebase Realtime Database queries filter and order on a single property that is under a fixed path/name under each child node of the location where you run the query. In your case the property is under profile/email, so your query becomes:

ref.child("users").orderByChild("profile/email").equalTo(email);

But note that your rules will reject this query, since they request to read data from /users and you don't grant anyone permission to read data from there. Firebase security rules are enforced when you attach a listener, and can't be used to filter data. To learn a lot more about this, read the documentation section called rules are not filters and the many questions mentioning that same phrase.

To quickly test the above query, you can temporarily grant every access to /users. Just be sure to change it back before sharing your app with any users.

To properly secure the data you'll need to verify in your security rules that the user is only trying to read their own data. You can do this with query based security rules. In your case they'd look something like this:

"users": {
  ".read": "auth.email != null &&
            query.orderByChild == 'profile/email' &&
            query.equalTo == auth.token.email"
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807