Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h1>The Data Structure</h1> <p>When building with Firebase, denormalizing your data is key. In your scenario I would suggest maintaining a secondary index which only contained the names of your animals with the unique key for loading the details. For example:</p> <pre><code>{ "names": { "Dog": 0, "Cat": 1, "Cow": 2 }, "animals": { 0: {name:"Dog", details:{somestuffhere}}, 1: {name:"Cat", details:{somestuffhere}}, 2: {name:"Cow", details:{somestuffhere}} } } </code></pre> <p>Now you can use a normal Firebase reference to load all the children of <code>/names</code> and you can then decide which details you want to load. </p> <p>When you add a new animal, just make sure to add a corresponding <code>/names</code> entry too.</p> <h1>Using this Structure with AngularJS</h1> <p>You're correct that AngularFire will load all the data of a given path, however we can limit this using our new data structure. Instead of using a single, generic AngularFire which loads all our data, we can use multiple AngularFires and be more selective.</p> <p>This first AngularFire loads our list of names.</p> <pre><code>// Load the list of names to $scope.names angularFire(new Firebase("http://[Your Firebase].firebaseio.com/names"), $scope, "names")); </code></pre> <p>Then once a user selects an animal, a new AngularFire for the path <code>/names/{Animal}</code> is used to dynamically load the details of that animal. In this example, it is assumed the unique key for the animal is stored in the <code>animalKey</code> variable</p> <pre><code>// Load the specific animal details to $scope.animal angularFire(new Firebase("http://[Your Firebase].firebaseio.com/animals/").child(animalKey), $scope, "animal")); </code></pre> <p>Now the data for our animal is exposed on <code>$scope.animal</code> and we haven't loaded all the unneeded data about the other animals.</p> <h1>Safely adding new animals</h1> <p><em>Addressing a comment on this answer</em></p> <p>As general advice, never use incremented integers as keys in Firebase. Due to the realtime nature of Firebase the likelyhood that two users would add a new item with the same incremented integer key (in this case, <code>3</code>), at the same time is very high, which would result in the overwriting of one of their entries. Use Firebase's <a href="https://www.firebase.com/docs/javascript/firebase/push.html" rel="nofollow noreferrer"><code>.push()</code></a> instead. </p> <p>In your scenario, what you would do is step around AngularFire and use <code>.push</code> on a Firebase ref. Try this:</p> <pre><code>var newAnimalRef = (new Firebase('http://[Your Firebase].firebaseio.com')) .child('animals') .push({name: 'Fish', details: ""}); </code></pre> <p>It will create a new child of <code>/animals</code> with a key like <code>-fj213jjkaisdja</code>. Then we can use <code>.once</code> to add the new item to the <code>/names</code> index: </p> <pre><code>newAnimalRef.once('value', function (snapshot) { (new Firebase('http://[Your Firebase].firebaseio.com')) .child('names') .child(snapshot.val().name) .set(snapshot.name()) }); </code></pre> <p>Then boom, we have added a child in a clean, safe way.</p> <h1>Closing Notes</h1> <ol> <li><p>Here is a <a href="https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html" rel="nofollow noreferrer">link to an official blog post</a> about denormalizing data and it is a generally good resource if you're coming from working with relational databases.</p></li> <li><p>Be careful when potentially creating multiple AngularFires associated to the same field on <code>$scope</code>. If you're not careful you can end up with changes to a single field being written to multiple paths in Firebase. To prevent this, either only tie AngularFire to an <code>$scope</code> which will be torn down regularly (i.e. a controller specific to the module displaying the animal data) or make use of the disassociate method passed to the resolved promise from AngularFire as I do in <a href="https://stackoverflow.com/a/20344334/1570248">my other answer</a>.</p></li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload