Search code examples
firebasefirebase-realtime-databaseangularfire2

Getting one record from firebase with AngularFire on json attribute value


Super simple one I am sure, but I'm new to Firebase it's stumping me. I have a JSON tree as follows in Firebase:

{
  "games" : {
    "-LKZxsIcVe3Uixrdxdau" : {
      "id" : "thing1",
      "name" : "This is a thing"
    },
    "-LKZxt57WpCd8ARMr1Cy" : {
      "id" : "thing2",
      "name" : "This is another thing"
    },
    "-LKZxtm8udMhEyZ3tHd5" : {
      "id" : "thing3",
      "name" : "And yet another thing"
    }
  }
}

I know that I can get an object by firebase ID with:

this.theThing = this.db.object('/games/-LKZxtm8udMhEyZ3tHd5').valueChanges();

How do I get a single object on id though please?

I've seen how to query lists using equalTo. Is that the way to do it? If so, how do I return a single object and assign it to my this.theThing variable as above so that it also gets updated in realtime etc?

Further, is it efficient to query in this way, or should I actually be querying by Firebase ID?


Solution

  • You'll need to query with the list method.

    this.theThing = this.db.list('/games', ref => ref
      .orderByChild('id')
      .equalTo('thing3')
      .limitToFirst(1)
    )
    .valueChanges();
    

    This won't set your variable as the object -LKZxtm8udMhEyZ3tHd5 instead it will set this.theThing as an Observable. What you might want to do is pipe the result into an RxJs Promise to get the desired result like;

    this.db.list('/games', ref => ref
      .orderByChild('id')
      .equalTo(someId)
      .limitToFirst(1)
    )
    .valueChanges()
    .map(first())
    .toPromise()
    .then(snapshots => {
      this.theThing = snapshots[0];
    });
    

    This should set this.theThing as the desired object -LKZxtm8udMhEyZ3tHd5. You'll be able to reference this.theThing.id which will have thing3 as the value.