Shiv Kumar Baghel
Shiv Kumar Baghel

Reputation: 2480

Filter data with .indexOn rules in Firebase realtime database with AngularJS

I'm using FireBase realtime database structure like shown below. and want to extract all model which has red color.

FireBase

{
  "models": {
    "model1": {
      "modelName": "model 1",
      "color": {
        "red": true,
        "blue": true,
        "green": true
      }
    },
    "model2": {
      "modelName": "model 2",
      "color": {
        "yellow": true,
        "blue": true,
        "green": true
      }
    },
    "model3": {
      "modelName": "model 3",
      "color": {
        "red": true,
        "yellow": true,
        "pink": true
      }
    },
    "model4": {
      "modelName": "model 4",
      "color": {
        "red": true,
        "orange": true,
        "white": true
      }
    }
  }
}

i tried using below query but not getting expected result.

AngularJS

let fbRef = firebase.database().ref('models');

fbRef
    .orderByChild('red')
    .equalTo(true)
    .once('value', function(data){
      console.log('result : ', data);
    });

FireBase Rules

{
  "rules": {
    ".read": true,

    "$modelID": {
      ".read": true,
      ".indexOn": ["red", "blue", "green", "orange", "pink", "white", "yellow"]
    }

  }
}

Expected Results

{
  "model1": {
    "modelName": "model 1",
    "color": {
      "red": true,
      "blue": true,
      "green": true
    }
  },
  "model3": {
    "modelName": "model 3",
    "color": {
      "red": true,
      "yellow": true,
      "pink": true
    }
  },
  "model4": {
    "modelName": "model 4",
    "color": {
      "red": true,
      "orange": true,
      "white": true
    }
  }
}

Upvotes: 0

Views: 253

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83093

You should order by 'color/red', as follows:

  fbRef
    .orderByChild('color/red')
    .equalTo(true)
    .once('value', function(data) {
      //Use the val() method of the DataSnapshot
      console.log('result : ', data.val());
      //Or loop over children
      data.forEach(function(childSnapshot) {
        var childKey = childSnapshot.key;
        var childData = childSnapshot.val();
        console.log('childKey : ', childKey);
        console.log('childData : ', childData);
      });
    });

Since you get a DataSnapshot, you may either use the val() method to get the result as an object or use forEach() to "enumerates the top-level children in the DataSnapshot". One of the difference between the two ways is that "the ordering of data in the JavaScript object returned by val() is not guaranteed to match the ordering on the server" as explained in the doc.

Upvotes: 1

Related Questions