Reading nested data from Firebase returns something else than an array

convert firebase object to array
firebase retrieve data
firebase snapshot to array
firebase console
firebase push to array
firebase push array of objects
firebase array
firebase web read data

Trying to read (and expect) a nested array like this:

var array = [
0: {subArrayy: {...}, title: "Title"}, 
1: {subArray]: {...}, title: "Title"},
...

However after reading and (!) outputting, the result is fine. My web console shows me the array and everything seems good. BUT doing array.length returns 0. And any iteration returns undefined.

I've tried using ladosh _.toArray thing that I've seen earlier, but it does absolutely nothing.

var locations = []; // Empty array

  var ref = db.ref("locations/");
  ref.once("value", function(snapshot) {

    snapshot.forEach(function(item) {
      var itemVal = item.val();
      locations.push(itemVal); // Adding new items seems to work at first

    });

  });
  console.log(locations, locations.length);

Output:

chrome output

I expected it to be iterable, in the way I could just use array0 to navigate.

Firebase reads data asynchronously, so that the app isn't blocked while waiting for network traffic. Then once the data is loaded, it calls your callback function.

You can easily see this by placing a few log statements:

console.log("Before starting to load data");
ref.once("value", function(snapshot) {
  console.log("Got data");
});
console.log("After starting to load data");

When you run this code the output is:

Before starting to load data

After starting to load data

Got data

This is probably not the order you expected, but it explains exactly why you get a zero length array when you log it. But since the main code continued on straight away, by the time you console.log(locations, locations.length) the data hasn't loaded yet, and you haven't pushed it to the array yet.


The solution is to ensure all code that needs data from the data is either inside the callback, or is called from there.

So this will work:

var locations = []; // Empty array

var ref = db.ref("locations/");
ref.once("value", function(snapshot) {

  snapshot.forEach(function(item) {
    var itemVal = item.val();
    locations.push(itemVal);
  });

  console.log(locations, locations.length);

});

As will this:

function loadLocations(callback) {
  var locations = []; // Empty array

  var ref = db.ref("locations/");
  ref.once("value", function(snapshot) {
    snapshot.forEach(function(item) {
      var itemVal = item.val();
      locations.push(itemVal);
    });
    callback(locations);
  });
});

loadLocations(function(locations) {
  console.log(locations.length);
});

A more modern variant of that last snippet is to return a promise, instead of passing in a callback.

function loadLocations() {
  return new Promise(function(resolve, reject) {
    var locations = []; // Empty array

    var ref = db.ref("locations/");
    ref.once("value", function(snapshot) {
      snapshot.forEach(function(item) {
        var itemVal = item.val();
        locations.push(itemVal);
      });
      resolve(locations);
    });
  })
});

And you can then call it like this:

loadLocations().then(function(locations) {
  console.log(locations.length);
});

Or with modern JavaScript you can use async / await and do:

let locations = await loadLocations()
console.log(locations.length);

Just keep in mind that this last snippet still has the same asynchronous behavior, and the JavaScript runtime (or transpiler) is just hiding it from you.

Retrieving Data, The REST API accepts several query parameters when reading data from our Firebase Specifying print=pretty returns the data in a human-readable format. Then, you combine orderBy with any of the other five parameters: ordered by deeply nested children, rather than only children one level down. Hi all, I'm having a lots of problems trying to retrieve data from the firebase database and moving that data to a unity dictionary. So I would like to do this, to just retrieve the data one time and then place all the data to a dictionary, the problem is that I can't find the way to do it if the dictionary is a nested dictionary.

Placing a sleep function for about 300ms seems to fix the problem. I think it has something to do with syncing, though not entirely sure. It just needs some time to process the query and assign everything, I suppose.

Structure Your Database, Avoid nesting data; Flatten data structures; Create data that scales The user alovelace might have a database entry that looks something like this: In addition, when you grant someone read or write access at a node in your The index is faster and a good deal more efficient than querying or scanning the data. We can insert, read, update, delete data from Firebase Realtime Database. By default, these operations access to database is restricted so only authenticated users can read or write data. II. Way to read/write data 0. Add Firebase to Android App 0.1 Create Firebase Project and Add Firebase Config file

Using await on read functions also seems to help.

Best Practices: Arrays in Firebase, In particular, if all of the keys are integers, and more than half of the it easier to see what one can and can't do when storing array-like data. However, to help people that are storing arrays in Firebase, when you call .val() or use the REST api to read data, if the data looks like an array, Firebase will render it as an array. In particular, if all of the keys are integers, and more than half of the keys between 0 and the maximum key in the object have non-empty values, then Firebase will render it as an array.

How To Query Arrays of Data in Firebase | by Justin Tulk, How To Retrieve Some Values From A Firebase Object But Not ALL The Values. Justin Tulk. Follow. May 16, 2017 � 2 min read return databaseRef.child('videos' ).child(id).on('value', s => s) Should your request exceed more than a handful, I recommend using something like Bluebird to do this concurrently without� If no data exists at the location, calling getValue() returns null. In this example, ValueEventListener also defines the onCancelled() method that is called if the read is canceled. For example, a read can be canceled if the client doesn't have permission to read from a Firebase database location.

Specifying nested and repeated columns | BigQuery, Rather than preserving a relational schema such as a star or snowflake schema, When you load nested and repeated data, your schema cannot contain more The nested depth limit is independent of whether the STRUCT s are scalar or array-based. return fmt.Errorf("bigquery.NewClient: %v", err) } defer client. Close() There are two ways to retrieve data stored in Cloud Firestore. Either of these methods can be used with documents, collections of documents, or the results of queries:

Adding data | Firestore, Firestore always stores numbers as doubles, regardless of what type of number return new City(data.name, data.state, data.country) But sometimes there isn' t a meaningful ID for the document, and it's more Important: Unlike "push IDs" in the Firebase Realtime Database, Firestore Update fields in nested objects. There are several ways to write data to Cloud Firestore: Set the data of a document within a collection, explicitly specifying a document identifier.

Comments
  • Please show both the code that writes the database as well as the code that reads it. Right now we have to guess what the data actually looks like under "locations".
  • Your console.log is being called before your async function ref.once has finished. Chrome will log the empty array initially, and then once the process has been complete fill in the missing parts except, apparently, stupidly, the data length. You should move your log inside the ref.once.
  • @DougStevenson I used this for my reference link This IS the code that reads it. I've been having a lot of trouble figuring out how to use JSON with Javascript and decided to upload my code manually through Firebase console.
  • I'm asking you to also edit the question to show the code that writes the database, or at least describe the structure of the data that exists immediately under locations. Without seeing that, we don't know what exactly what the reading code is going to receive.
  • Move the console.log() inside the callback function. It should return the correct length. Adding a setTimeout will throw incorrect results if the data download takes more than 300ms.