YannickHelmut
YannickHelmut

Reputation: 555

Query by child and key

What I'm trying to achieve:

I have a list of patients and different users can access them. I therefore have this structure in Firebase

screenshot ot firebase structure

All patients are in patients ref. So basically, I'd like to retrieve the patients that match on the key which is the user's UID. Ideally, I will filter that data on the read/write/detail part as well since the secretary for example would have writing rights to modify the contact data but no access to the detail, while an apprentice would have full detail no modifying rights.

What I have (which doesn't work):

var patientsRef = firebase.database().ref('patients').orderByChild('users').orderByKey().equalTo(uid);

And there's the problem: I can't find an apporpriate reference to my question in the documentation. What am I doing wrong ?

Upvotes: 1

Views: 117

Answers (2)

vzsg
vzsg

Reputation: 2896

Using such a nested structure is generally advised against with Firebase. It makes querying close to impossible (as you've experienced), along with applying any access control to the patient data.

Keep in mind that a query requires read access to the parent node, and if that is granted, no children data can be hidden, ever.


The typical solution would be moving this patient-user relationship to a separate root node. The actual patient data should only be readable one-by-one, if there is a matching relationship (ACL) node for them.

Preferably "invert" the relationship too: store the patients per user, not users per patient, so your application can directly display them as a list.

A proposal:

/patients
    /PATIENTID1
        ... sensitive data
    /PATIENTID2
        ... sensitive data

/users
    /USERID1
        ...
    /USERID2
        ...

/user-patients
    /USERID1
        /PATIENTID1
            "name": "Patient name" (redundant copy for easy display)
            "detail": true,
            "write": false,
            ...

Your application will load /user-patients to show a personalized list of the patients the current user can access. Security rules can also use this directly (with the root variable) to make sure no one reads or writes what they are not supposed to.

Upvotes: 3

Mathew Berg
Mathew Berg

Reputation: 28750

Edit: read the comment thread of this answer on why you should not do it this way. Please see vzsgs answer.


I would suggest adding a different part to your json so that it can be queried. One of the main points in firebase is to structure the data to be easily query-able and so sometimes you have to duplicate data. (P.s. next time paste your json)

{
    "c237CV45SbhHfaRoicVyvFuy8e88" : {
        "firstName" : "Emeline",
        "gender": "f",
        "lastname": "Zagaroli",
        "users": {
            "p0R3CV45SBgGfaRoicVyvFuy8tq1": {
                "detail": true,
                "read": true,
                "write": true
            }
        },
        "usersAssoc": {
            "p0R3CV45SBgGfaRoicVyvFuy8tq1": true
        }
    }
}

This way you can write a query like so:

var patientsRef = firebase.database().ref('patients').orderByChild('usersAssoc/p0R3CV45SBgGfaRoicVyvFuy8tq1').equalTo(true);

Upvotes: 1

Related Questions