0

The JSON data shows available disciplines in various colleges:

{
  "AvailableDisciplines": {
    "4JN": {
      "Disciplines": {
        "CV": {
          "disciplineCode": "CV",
          "disciplineName": "Civil Engineering",
          "siNo": "1"
        },
        "EC": {
          "disciplineCode": "EC",
          "disciplineName": "Electronics and Communication Engineering",
          "siNo": "2"
        },
        "EE": {
          "disciplineCode": "EE",
          "disciplineName": "Electronics and Electricals Engineering",
          "siNo": "3"
        }
      }
    },
    "4MT": {
      "Disciplines": {
        "EE": {
          "disciplineCode": "EE",
          "disciplineName": "Electronics and Electricals Engineering",
          "siNo": "1"
        },
        "CS": {
          "disciplineCode": "CS",
          "disciplineName": "Computer Science Engineering",
          "siNo": "2"
        },
        "IS": {
          "disciplineCode": "IS",
          "disciplineName": "Information Science Engineering",
          "siNo": "3"
        }
      }
    },
    "1KT": {
      "Disciplines": {
        "TE": {
          "disciplineCode": "TE",
          "disciplineName": "Telecommunication Engineering",
          "siNo": "1"
        },
        "CS": {
          "disciplineCode": "CS",
          "disciplineName": "Computer Science Engineering",
          "siNo": "2"
        },
        "IS": {
          "disciplineCode": "IS",
          "disciplineName": "Information Science Engineering",
          "siNo": "3"
        }
      }
    }
  }
}

where 4JN, 4MT and 1KT are College Code. If I want to query all the colleges that offers Civil Engineering discipline, I'll have to write a deep query on AvailableDisciplines node. And the query code is:

FirebaseDatabase.getInstance().getReference()
    .child("Trial").child("AvailableDisciplines")
    .orderByChild("Disciplines/EE").startAt("")
    .addListenerForSingleValueEvent(new ValueEventListener() {      
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            Log.v("log", "datasnapshot: " + String.valueOf(dataSnapshot));
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
}));

I'm able to fetch the data as per my expectation. But, I'm not getting how to write .indexOn rules for this case. Could you help me please?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Nishanth Sreedhara
  • 1,266
  • 1
  • 19
  • 34

2 Answers2

0

Here is a sample rule code: As you have seen below does not matter how deep is the key.

{
  "rules": {
    ".read": true,
    ".write": "auth != null",
    "AvailableDisciplines": {
      "$otherKeys":{
       ".indexOn":["disciplineName"] 
      }
    }
   }
 }

You may add more key at same level ie: ".indexOn":["disciplineName", "disciplineCode","siNo"]

Cappittall
  • 3,300
  • 3
  • 15
  • 23
  • Thank you. I tried your rules but I'm getting this warning: **Using an unspecified index. Consider adding '".indexOn": "Disciplines/EE"' at Trial/AvailableDisciplines to your security and Firebase Database rules for better performance** – Nishanth Sreedhara Oct 11 '18 at 04:13
  • 1
    I have almost the same structure that indexed the keys. Let me check again. But honestly above what Frank says is more correct – Cappittall Oct 11 '18 at 04:19
0

In your current data model, your query should check for an actual value (not for the existence of a node). For example:

FirebaseDatabase.getInstance().getReference()
    .child("Trial").child("AvailableDisciplines")
    .orderByChild("Disciplines/EE/disciplineCode").equalTo("EE")
    ...

Now you have an actual property that you can define the index on:

{
  "rules": {
    "Trial": {
      "AvailableDisciplines": {
        "$collegecode": {
          "Disciplines": {
            "$discipline": {
              ".indexOn": "disciplineCode"
            }
          }
        }
      }
    }
  }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thank you. But I'm getting this warning: "Using an unspecified index. Consider adding '".indexOn": "Disciplines/EE/disciplineCode"' at Trial/AvailableDisciplines to your security and Firebase Database rules for better performance." – Nishanth Sreedhara Oct 11 '18 at 04:07
  • 1
    Argh... that's right. In that case I'm not sure if the query is possible. See my answer here: https://stackoverflow.com/questions/27207059/firebase-query-double-nested – Frank van Puffelen Oct 11 '18 at 04:11
  • Oh! I wanted to Deep path update my 'denormalized' data with this query. On a different context, if I use Firestore and not worry about number of reads, is it ok, if I completely 'normalize' my database? – Nishanth Sreedhara Oct 11 '18 at 04:17