Awaiting all results from Firebase Query?

Viewed 36

I'm gonna do my best to explain this as I'm new to using javascript along with Firebase SDK. Here is the mock data I have:

    "Via" : {
    "00zz00" : {
      "coordinates" : "0,0",
      "order_number" : 1,
      "route_id" : "xyz987",
      "via_id" : "00zz00"
    },
    "1a2b3c" : {
      "coordinates" : "10,-10.1",
      "order_number" : 1,
      "route_id" : "abc123",
      "via_id" : "1a2b3c"
    },
    "2b3c4d" : {
      "coordinates" : "45.5,-24.7",
      "order_number" : 2,
      "route_id" : "abc123",
      "via_id" : "2b3c4d"
    },
    "3c4d5e" : {
      "coordinates" : "45.8,-24.0",
      "order_number" : 4,
      "route_id" : "abc123",
      "via_id" : "3c4d5e"
    },
    "4d5e6f" : {
      "coordinates" : "20.0,-20.0",
      "order_number" : 3,
      "route_id" : "abc123",
      "via_id" : "4d5e6f"
    }
  }

I first made a query using .on() with the "child_added" event to fill an array with the coordinates of every result:

var waypoints = new Array();
var refVia = firebase.database().ref("Via");
refVia
    .orderByChild("route_id")
    .equalTo("abc123")
    .on("child_added", function (snapshot) {
        waypoints.push(snapshot.val().coordinates);
    });

I am calling another API and using the array to create a route and I realized I was getting an error since my array was still empty. I found a solution on here mentioning using .once().then() with the "value" event along with a promise but I'm a bit confused about how to go from here. I tried this but I'm a bit lost from here.

var refVia = firebase.database().ref("Via");
    return refVia
        .orderByChild("route_id")
        .equalTo("abc123")
        .once("value")
        .then(
            function (snapshot) {
                var via = [];
                
                //Not sure what to do here to add the entries to my array...

                return Promise.all(via);

            },
            function (error) {
                
                console.error(error);
            }
        );
1 Answers

I understand that you need to iterate over the keys of the nodes (which are equal to the via_id subnode values) in order to define promises that you add to the via Array. So the following should do the trick:

  var refVia = firebase.database().ref('Via');
  return refVia
    .orderByChild('route_id')
    .equalTo('abc123')
    .once('value')
    .then((snapshot) => {
      const via = [];
      for (const [key, value] of Object.entries(snapshot.val())) {
        console.log(`${key}: ${value.via_id}`);
        via.push(*** here build the Promise based on the key value ***)

        // example with Axios https://github.com/axios/axios
        via.push(axios.get('https://..../via?ID=' + key));
      }
      
      return Promise.all(via);
    })
    .then(results => {
      // results is an Array of results of each call to the API
      // For example
      results.forEach(r => {
        // ...
      })
    })
    .catch((error) => {
      console.error(error);
    });
Related