title: How to set up multiple firebase .on() listeners and trigger function after all have resolved
body: <p>I have multiple <code>on()</code> listeners set up on different nodes to get data required for generating some tables of data. After a listener updates, it regenerates all the tables on the website. The problem is that on the first webpage load, it has to regenerate the tables once for each <code>.on()</code> listener, this is excessive. I tried making each listener into a promise so that I could run <code>gen_tables()</code> only after they all resolve and it worked great, except that the listeners seem to have been called off and no longer listen. How can I have the <code>gen_tables()</code> run only once on first load, but then still have my multiple listeners continue listening?</p>
  <p>Here is my code that works, but has to run <code>gen_tables()</code> 6 times</p>
  <pre><code>//LISTENER - CURRENT_WEEK_DATA
  
  db.ref(`weeks/${currentweek}`).on(&quot;value&quot;, (snap) =&gt; {
    currentWeekData = snap.val();
    console.log(&quot;DOWNLOADING currentWeekData From Firebase: &quot;, currentWeekData);
    gen_tables();
  });
  
  //LISTENER - ORDERS_PROCESSING
  db.ref(&quot;orders_processing&quot;).on(&quot;value&quot;, (snap) =&gt; {
    orders_processing = snap.val();
    console.log(
      &quot;DOWNLOADING orders_processing From Firebase: &quot;,
      orders_processing
    );
    gen_tables();
  });
  
  //LISTENER - ORDERS_META
  db.ref(&quot;orders_meta&quot;).on(&quot;value&quot;, (snap) =&gt; {
    orders_meta = snap.val();
    console.log(&quot;DOWNLOADING orders_meta From Firebase&quot;);
    gen_tables();
  });
  
  //LISTENER - ORDERS NEXT WEEK Do i neeed this?
  db.ref(&quot;orders_next_week&quot;).on(&quot;value&quot;, (snap) =&gt; {
    orders_next_week = snap.val();
    console.log(&quot;orders_next_week DOWNLOADED From Firebase: &quot;, orders_next_week);
    gen_tables();
  });
  
  //LISTENER - PRODUCTS
  db.ref(&quot;products&quot;).on(&quot;value&quot;, (snap) =&gt; {
    console.log(&quot;DOWNLOADING PRODUCTS&quot;);
    products = snap.val();
    gen_tables();
  });
  
  //LISTENER -PRODUCTS_META
  db.ref(&quot;products_meta&quot;).on(&quot;value&quot;, (snap) =&gt; {
    console.log(&quot;DOWNLOADING PRODUCTS_META&quot;);
    products_meta = snap.val();
    gen_tables();
  });
  </code></pre>
  <p>and here is the code with the Promise.all method to wait until all  <code>.on()</code> have resolved to run <code>gen_tables()</code> only once, but doesn't continue listening after first load:</p>
  <pre><code>const listener = (ref) =&gt; {
    return new Promise((resolve, reject) =&gt; {
      const onError = (error) =&gt; reject(error);
      const onData = (snap) =&gt; resolve(snap.val());
  
      db.ref(ref).on(&quot;value&quot;, onData, onError);
    });
  };
  
  let listeners = [
    listener(&quot;orders_meta&quot;),
    listener(&quot;orders_next_week&quot;),
    listener(&quot;orders_processing&quot;),
    listener(&quot;products&quot;),
    listener(&quot;products_meta&quot;),
    listener(`weeks/${currentweek}`),
  ];
  
  Promise.all(listeners).then(function (values) {
    console.log(values);
    orders_meta = values[0];
    orders_next_week = values[1];
    orders_processing = values[2];
    products = values[3];
    products_meta = values[4];
    currentWeekData = values[5];
    gen_tables();
  });
  </code></pre>