0

I'm trying to figure out how to append values to a list in a Firebase object using AngularFire2. The use case is the creation of a simple scoreboard where the score is saved every time it changes by pushing the following Score object to a list:

{
    points: [15, 11],
    sets: [2, 1],
    timestamp: new Date()
}

A Scoreboard object in the database then looks as follows:

{
    event: 'Volleybal',
    home: 'Londen',
    away: 'Manchester',
    scores: [Score]
}

Where the scores array is an array of Score objects as described above. I need to be able to perform two tasks:

  1. Query the Scoreboard list in the Firebase database to obtain the correct event (assuming the event is unique).
  2. Update the scores array by pushing new Score objects every time the score changes.

Is this the right schema design and how can I perform these tasks using AngularFire2?

1 Answer 1

2

It looks like the above schema would cover your use cases. I'd recommend that the scores property of the Scoreboard object is handled in your code (and stored) as an Object vs. an array.

Assuming the event property is unique to all the Scoreboard objects, you can retrieve this from Firebase with something like the below.

const event = 'Volleyball';

const scoreboards = af.database.list('scoreboards', {
  query: {
    orderByChild: 'event',
    equalTo: 'large' 
  }
});

However, if you have a unique key inside the object, it might be worth considering to use that key for the Scoreboard object itself, so the Scoreboards resource would look like the below

{
    'Volleyball': {
        home: 'London',
        away: 'Manchester',
        scores: {}
    },
    'Football': {
        home: 'London',
        away: 'Manchester',
        scores: {}
    },
    ...
}

Doing this would allow you to retrieve/update this object like below.

// Get Scoreboard
const event = 'Volleyball';
const scoreboard = af.database.object('scoreboards/' + event);

// Add a new score to the scores property of Scoreboard
af.database.list('/scoreboards/' + event + '/scores').push({
  points: [15, 11],
  sets: [2, 1],
  timestamp: new Date()
});

It's worth noting that Firebase doesn't actually store Arrays; if you present Firebase with an array it turns it into an object, with the keys being the indices of the array. https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html

Edited answer per comment below To display the latest stored value, you could get the value using something like the below.

const event = 'Volleyball';
const scoreboard = af.database.list('/scoreboards/' + event + '/scores', {
  query: {
    orderByChild: 'timestamp',
    limitToLast: 1
  }
});

scoreboard.subscribe(list => {
   list.forEach(score => {
       // Can access the values of the Score object here
       console.log(score.points);
   });
});
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the response, this works. How can I display the latest (in time) stored value in my angular template?
Have updated my answer per your comment, once you've got the values you can use them normally in your Angular2 template.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.