Search code examples
angularjsfirebasemany-to-manyfirebase-realtime-database

Firebase angular many to many relation query


I have a fairly simple json structure of groups and people and I am struggling to get/read a list of the group names for each person from firebase. This is what I tried. I spent a couple of days debugging unsuccessfully. Help much appreciated.

JSON:

{
"groups" : {
"one" : {
  "members" : {
    "-KLxjv9OnQB2l5Ohr-7I" : true
  },
  "name" : "group alpha"
},
"two" : {
  "members" : {
    "-KM4oXjftRZZ5DXYt4B2" : true
  },
  "name" : "group beta"
},
"three" : {
  "members" : {
    "-KM4oXjftRZZ5DXYt4B2" : true
  },
  "name" : "group gamma"
}
},
"persons" : {
"-KLxjv9OnQB2l5Ohr-7I" : {
  "groups" : {
    "one" : true
  },
  "personName" : "name1",
  "personTitle" : "title1"
},
"-KM4oXjftRZZ5DXYt4B2" : {
  "groups" : {
    "two" : true
  },
  "personName" : "name2",
  "personTitle" : "title2"
  }
 }
}

APP.JS:

$scope.personsGroup = function(personObj){
var baseRef = new Firebase("https://un-cms-13264.firebaseio.com/");
var personsRef = baseRef.child('persons');
var groupsRef = baseRef.child('groups');
var res=[];
    for(var i=0;i<Object.keys(personObj.groups).length;i++){
    var groupKey=Object.keys(personObj.groups)[i]
    res.push($firebaseArray(groupsRef.child(groupKey)));
    };
    return res;

}

HTML:

<div class="row" ng-repeat="person in persons">

<div class="col-lg-3"></div>
<div class="col-lg-3">{{person.personName}}</div>
<div class="col-lg-3"></div>
<div class="col-lg-3 groupsList">
<ul><li ng-repeat="group in personsGroup(person)">{{group.name}}</li></ul>
</div>

</div>

Solution

  • The best way would be to attach $firebaseArray to a $scope variable:

    var ref = new Firebase("https://un-cms-13264.firebaseio.com/").child("persons").child(some-person).child("groups");
    $scope.personsGroup = $firebaseArray(ref);
    
    // When loaded
    $scope.personsGroup.$loaded(function(data) {
         // can do something
    }, function(error) {
         // error
    });
    

    How you determine some-person is up to you. You could query the persons tree and store all the persons or store it inside an array or object.

    <ul>
        <li ng-repeat="(key, value) in personsGroup">{{ key }}</li>
    </ul>
    

    I would not advise personGroup(person) because $firebaseArray is an asynchronous call and I feel like it could be real jumpy. Be smart with it, you could also just get the entire persons tree in one call if you wanted:

    var ref = new Firebase("https://un-cms-13264.firebaseio.com/").child("persons");
    $scope.persons = $firebaseArray(ref);
    

    And do some iterating of that.