3

I am pretty new to the 'game' and was wondering if it's possible to order newly added data (through a form and inputs) to the Firebase numerically so each new data entry gets the ID (number of the last added data +1). To make it more clear, underneath you can find a screenshot of how data is currently being added right now. The datapoint 0-7 are existing (JSON imported data) and the ones with the randomly created ID belong to new entries. I would like to have the entries to comply to the numbering inside of my Firebase, because otherwise my D3 bar chart won't be visualised.

var firebaseData = new Firebase("https://assignment5.firebaseio.com");

function funct1(evt)
{
 var gameName = $('#nameInput').val();
      var medalCount = $('#medalsInput').val();
      var bool = $('#boolInput').is(':checked');
firebaseData.push().set({games: gameName, medals: medalCount, summergames: bool});
 evt.preventDefault();
}
var submit = document.getElementsByTagName('button')[0];
submit.onclick = funct1;

UPDATE:

function funct1(evt) 
{ 
var gameName = $('#nameInput').val(); 
var medalCount = $('#medalsInput').val(); 
var bool = $('#boolInput').is(':checked');
for (var i = 0; i < 10; i++) 
{ 

firebaseData.child('7' + i).set({games: gameName, medals: medalCount, summergames: bool}(i)); };

Problem:

SYIL
  • 43
  • 1
  • 4
  • Could you provide some code? – David East Mar 07 '14 at 16:57
  • Hi David, this is how I gather the data currently: var firebaseData = new Firebase("https://assignment5.firebaseio.com"); function funct1(evt) { var gameName = $('#nameInput').val(); var medalCount = $('#medalsInput').val(); var bool = $('#boolInput').is(':checked'); firebaseData.push().set({games: gameName, medals: medalCount, summergames: bool}); evt.preventDefault(); } var submit = document.getElementsByTagName('button')[0]; submit.onclick = funct1; – SYIL Mar 07 '14 at 17:01

1 Answers1

2

There are two ways to generate ids for your document nodes.

  1. Calling .push() on your reference will generate that unique id.
  2. Calling .set() on your reference will allow you to use your own id.

Right now you're using .push().set({}), so push will generate an new id and the set will simply set the data.

// These two methods are equivalent
listRef.push().set({user_id: 'wilma', text: 'Hello'});
listRef.push({user_id: 'wilma', text: 'Hello'});

Using .set() without .push() will allow you to control your own id.

Using .push():

When managing lists of data in Firebase, it's important to use unique generated IDs since the data is updating in real time. If integer ids are being used data can be easily overwritten.

Just because you have an unique id, doesn't mean you can't query through your data by your ids. You can loop through a parent reference and get all of the child references as well.

    var listRef = new Firebase('https://YOUR-FIREBASE.firebaseio.com/items');

    // constructor for item
    function Item(id) {
        this.id = id;
    };

    // add the items to firebase
    for (var i = 0; i < 10; i++) {
        listRef.push(new Item(i));
    };

    // This will generate the following structure
    // - items
    //   - LGAJlkejagae
    //      - id: 0


    // now we can loop through all of the items
    listRef.once('value', function (snapshot) {
        snapshot.forEach(function (childSnapshot) {
            var name = childSnapshot.name();
            var childData = childSnapshot.val();
            console.log(name); // unique id
            console.log(childData); // actual data
            console.log(childData.id); // this is the id you're looking for
        });
    });

Within the childData variable you can access your data such as the id you want.

Using .set()

If you want to manage your own ids you can use set, but you need to change the child reference as you add items.

    for (var i = 0; i < 10; i++) {
        // Now this will create an item with the id number
        // ex: https://YOUR-FIREBASE.firebaseio.com/items/1
        listRef.child('/' + i).set(new Item(i));
    };

    // The above loop with create the following structure.
    // - items
    //   - 0
    //     - id: 0

To get the data you can use the same method above to loop through all of the child items in the node.

So which one to use?

Use .push() when you don't want your data to be easily overwritten.

Use .set() when your id is really, really important to you and you don't care about your data being easily overwritten.

EDIT

The problem you're having is that you need to know the total amount of items in the list. This feature is not implemented in Firebase so you'll need to load the data and grab the number of items. I'd recommend doing this when the page loads and caching that count if you really desire to maintain that id structure. This will cause performance issues.

However, if you know what you need to index off of, or don't care to overwrite your index I wouldn't load the data from firebase.

In your case your code would look something like this:

// this variable will store all your data, try to not put it in global scope
var firebaseData = new Firebase('your-firebase-url/data');
var allData = null;
// if you don't need to load the data then just use this variable to increment
var allDataCount = 0; 

// be wary since this is an async call, it may not be available for your
// function below. Look into using a deferred instead.
firebaseData.once('value', function(snapshot) {
  allData = snapshot.val();
  allDataCount = snapshot.numChildren(); // this is the index to increment off of
});

// assuming this is some click event that adds the data it should
function funct1(evt) { 
  var gameName = $('#nameInput').val(); 
  var medalCount = $('#medalsInput').val(); 
  var bool = $('#boolInput').is(':checked'); 
  firebaseData.child('/' + allDataCount).set({
     games: gameName, 
     medals: medalCount, 
     summergames: bool
  }); 
  allDataCount += 1; // increment since we still don't have the reference
};

For more information about managing lists in Firebase, there's a good article in the Firebase API Docs. https://www.firebase.com/docs/managing-lists.html

Community
  • 1
  • 1
David East
  • 31,526
  • 6
  • 67
  • 82
  • Hi David, thanks for the suggestion and information. I would like to use .set() and overwriting data isn't a big deal in my case. I have refactored a piece of my code as followed: function funct1(evt) { var gameName = $('#nameInput').val(); var medalCount = $('#medalsInput').val(); var bool = $('#boolInput').is(':checked'); for (var i = 0; i < 10; i++) { firebaseData.child('7' + i).set({games: gameName, medals: medalCount, summergames: bool}(i)); }; but this doesn't seem to work. I want the new data to start counting from 8. Tnx! – SYIL Mar 07 '14 at 21:10
  • Can you update that in the question rather than the comments? – David East Mar 07 '14 at 23:00
  • Thanks for your patience, I have updated a piece of code in the question area. I hope the problem an hopefully solution will be clearer now. – SYIL Mar 08 '14 at 16:20
  • Thanks for the answer! It did help me a lot. It's just silly that the d3 visualisation code wasn't able to grab the data behind the randomly created/numbered Firebase data IDs. – SYIL Mar 08 '14 at 17:06