0

I am very new to queries in Firebase and query-based rules. I am trying to use query-based rules to retrieve specific data from the database, if and only if the group_id passed in the query is matching the group_id in the database at the given user with {user_id}

Code

Database reference: ref(users/{user_id}

Query

db.ref()
    .orderByChild("group_id")
    .equalTo(group_id) <- variable
    .on("value", (snapshot) => {
        return snapshot.val();
    });

JSON

root: {
  "users" : {
    "{user_id}" : {
      "email" : "user@email.com",
      "group_uid" : "{group_id}",
      "name" : "username",
    },
}

Rules

users:{
  $user_id:{
      ".read": auth.uid != null 
               && query.orderByChild == 'group_id' 
               && query.equalTo == data.child('group_id').val()
    }
}

My goal is to fetch the information about the user (email, group_uid and name), but the result returns null, and I can't seem to understand why.

Jonas
  • 67
  • 1
  • 1
  • 6
  • 1
    Can you edit your question to show: 1) the JSON you're querying (as text, no screenshots please)? You can get this by clicking the "Export JSON" link in the overflow menu (⠇) on your [Firebase Database console](https://console.firebase.google.com/project/_/database/data). 2) the minimal, full rules, so that we can see where you are defining this? 3) The minimal `cb` implementation, and its output. – Frank van Puffelen Feb 03 '21 at 16:52
  • Thanks for the quick reply. Updated the question now – Jonas Feb 03 '21 at 17:25

1 Answers1

0

There are a few things wrong in your code/rules.

First off, you seem to be querying at the root, but are hoping to read the nodes under /users. So you'll want to fix that to:

db.ref("users")
    .orderByChild("group_id")
    .equalTo(group_id)

Second, indexes and rules need to be defined at the location in the JSON that the user reads. Since the above reads from /users, that's where you need to have the ".read" rule to allow the query:

users:{
  ".read": auth.uid != null 
           && query.orderByChild == 'group_id' 
           && query.equalTo == data.child('group_id').val()
}

I'm not really sure what the data.child('group_id').val(), but I doubt it'll work as you have it now. If you need more help defining your data structure, please update your question to show a more complete snippet of the JSON.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • My intention with `data.child('group_id').val()` was to access the value of the `group_uid` of the given user. Also I am trying to query at a given user with `db.ref(users/{user_id})` – Jonas Feb 03 '21 at 19:56
  • The query you showed `.orderByChild("group_id").equalTo(group_id)` only works when you run it on `/users` in the JSON you showed. – Frank van Puffelen Feb 03 '21 at 19:58
  • Okey thanks! So this query will order the users by the given `group_id`? My intention with the rule `query.equalTo == data.child('group_id').val()` was to ensure that the `group_id` given in the query is the same as the `group_id` value at the users. However, when the query is runned on `/users`, how do i access values from the users, such as `group_id`? – Jonas Feb 03 '21 at 20:17
  • I'm not sure that is possible. Firebase security rules only check whether the query is valid when it is attached. They can't check every child node now and in the future, as that wouldn't scale. You may have to change your data model to allow the use case, for example by storing the messages keyed by group id. – Frank van Puffelen Feb 03 '21 at 21:35
  • Okey thanks again. To ensure that i am targeting the correct child, is it possible to run the query at `ref("users/{user_id}")`? Then use the rule `query.equalTo == data.child('group_id').val()` to ensure that the group_id given in the query is the same as the group_id value at the given the given user with `{user_id}` – Jonas Feb 03 '21 at 21:43
  • No. As said: `The query you showed .orderByChild("group_id").equalTo(group_id) only works when you run it on /users in the JSON you showed.` But why do you want to use a query, if you know what node to return? If a user can only belong to a single group, consider setting that group as a custom claim on their profile - as shown in my answer to your [previous question](https://stackoverflow.com/questions/65993204/firebase-database-sending-payload-with-rest-request). – Frank van Puffelen Feb 03 '21 at 21:56
  • I tried to install the Admin SDK in my React Native project, but i get the following error when starting the project after importing `* as admin from "firebase-admin";`: `unable to resolve module fs....` - isn't is compatible with react native? – Jonas Feb 04 '21 at 08:08
  • I found a solution to my initial problem and ended up using queries. Thanks a lot for the help and effort Frank! – Jonas Feb 04 '21 at 12:20