title: How do I recursively search for results in Firestore?
body: <p>I'm new to Node and Firebase.</p>
  
  <p>I'm currently working on a crafting calculator for a game and have the game items stored in Firebase. Some items are composite items, for example:</p>
  
  <pre><code>1 Lumber Plank = 5 Logs
  </code></pre>
  
  <p>Based on such requirements, I've structured all the items as a single collection titled as <code>items</code> in Firebase.</p>
  
  <p>Log would be persisted as:</p>
  
  <pre><code>{
    "type": "basic",
    "name": "log"
  }
  </code></pre>
  
  <p>While lumber plank would be:</p>
  
  <pre><code>{
    "type": "composite",
    "name": "lumber plank",
    "materials": ["log"],
    "material_values": [5]
  }
  </code></pre>
  
  <p>With such a structure, I'm trying to construct a crafting tree by recursively searching through the database. A final structure would look as such:</p>
  
  <pre><code>{
      "name": "board",
      "count": 1,
      "materials": [
          {
              "name": "lumber plank",
              "count": 1,
              "materials": [
                  {
                      "name": "log",
                      "count": 5,
                      "materials": null
                  }
              ]
          }
      ]
  }
  </code></pre>
  
  <p>I'm having trouble with understanding the callbacks while debugging and this piece of code currently returns <code>undefined</code> followed by <code>log</code> (I'm assuming this comes from the <code>console.log</code> within the <code>search</code> function).</p>
  
  <pre class="lang-js prettyprint-override"><code>async function search(item, result, count) {
      let calcItem = {
          name: item,
          count: count
      };
  
      db.collection("items")
          .doc(item)
          .get()
          .then(doc =&gt; {
              const data = doc.data();
              if (data.type === basic) {
                  calcItem.materials = null;
                  result.push(calcItem);
                  return result;
              } else {
                  let materials = data.materials;
                  let materialsCount = data.material_values;
                  calcItem.materials = [];
                  for (let i = 0; i &lt; materials.length; i++) {
                      console.log(materials[i]);
                      search(materials[i], calcItem.materials, materialsCount[i]);
                  }
              }
          });
  }
  
  let item = "lumber plank";
  
  search(item, [], 1).then(result =&gt; console.log(result));
  </code></pre>
  
  <p>Would appreciate any pointers/tips here. Thanks</p>
  
  <hr>
  
  <p>Following feedback from Doug,</p>
  
  <p>I've kinda refactored my code based on your comments and I'm seeing some progress.</p>
  
  <pre class="lang-js prettyprint-override"><code>function recursiveSearch(item, count, result) {
      let calcItem = {
          name: item,
          count: count
      };
  
      dbSearch(item).then(function (doc) {
          const data = doc.data();
          console.log(data);
  
          if (data.type === basic) {
              calcItem.materials = null;
              result.push(calcItem);
              return result;
          } else {
              let materials = data.materials;
              let materialsCount = data.material_values;
              calcItem.materials = [];
              for (let i = 0; i &lt; materials.length; i++) {
                  recursiveSearch(materials[i], materialsCount[i], calcItem.materials);
              }
          }
      });
  }
  
  function dbSearch(item) {
      return Promise.resolve(db.collection("items")
          .doc(item)
          .get()
          .then());
  }
  </code></pre>
  
  <p>Log now outputs the search correctly.</p>
  
  <pre><code>{
    material_values: [ 5 ],
    materials: [ 'log' ],
    name: 'lumber plank',
    type: 'composite'
  }
  {
    name: 'log',
    type: 'basic'
  }
  </code></pre>
  
  <p>However, if I understand it correctly, if I were to add in this line it's still going to return undefined, am I right?</p>
  
  <pre><code>console.log(recursiveSearch("lumber plank", 1, [])
  </code></pre>
  
  <p>If so, how do I actually log out the entire item structure whilst completing all the recursive searches?</p>
  
  <p>Sorry if the question sounds kinda dumb. I primarily come from a Java background and dealing with promises/async/await is entirely new to me</p>