Converting duplicate JS code into a higher order function
From a short review;

Why hardcode the batch length to 500 ?
Why not have the batch length be a nice constant ?
You have even hard coded the length in the function name, which is really unfortunate
batchNumber++ is more canonical than batchNumber += 1
I would have gone for maxIndex = Math.min(startingIndex + 500, dataArray.length); because now you have a lot of calls to func with undefined as a document value
await requires runFunctionInBatchesOf500 to be async (it is missing now)
I would use Array.prototype.slice() to create batches as an array, and then use forEach on each slice/batch
const doc = getDocFromPath(key); &lt;- where does key come from, an evil global?

I personally would be mildly evil by adjusting the Array prototype so that I can keep chaining, FP style;
Array.prototype.mapSlice = function arrrayMapSlice(n){
  //Just return `this` if we get a non-sensical parameter
  if(isNaN(n) || n &lt;= 0){
    return this;
  }
  let start = 0, out = [];
  while(start &lt; this.length){
    out.push(this.slice(start, start+=n));
  }
  return out;
} 

async function runBatches(list, f, batchSize){
   batchSize = batchSize || 500;
   list.mapSlice(batchSize).forEach(batch =&gt; {
     const firestoreBatch = this.firestore.batch();
     batch.forEach(document =&gt; f(document, firestoreBatch ));
   });
   await batch.commit();
}