When I create a new document from my API, I would like to commit (or atomically update) a statistics collection which belongs to a root projects document:
const increment = firebase.firestore.FieldValue.increment(1)
let aggregation: LooseObject = {
totalProjects: increment,
tags: [],
categories: [],
}
const project = fakeProject() // some debug func to return a dummy project object
const projectRef = db.collection('projects').doc()
const projectStatsRef = db.collection('projects').doc('--stats--')
project.categories.forEach((category: string) => {
aggregation.categories[category] = increment
})
project.tags.forEach((tag: string) => {
aggregation.tags[tag] = increment
})
console.log(aggregation)
const batch = db.batch()
batch.set(projectRef, project)
batch.set(projectStatsRef, aggregation, {
merge: true,
})
batch.commit()
When I inspect the console, I get the following dump for my aggregation doc (this is the shape of the data that I would expect to see in the attached screenshot):
{
totalProjects: NumericIncrementTransform { operand: 1 },
tags: [
raid: NumericIncrementTransform { operand: 1 },
'attack-of-the-clone': NumericIncrementTransform { operand: 1 },
'star-wars': NumericIncrementTransform { operand: 1 }
],
categories: [ movie: NumericIncrementTransform { operand: 1 } ]
}
However when the doc is committed to firestore, only the following structure appears (the tags and categories arrays are both empty)

From my understanding, merge should perform a deep merge of all nested objects. If this is not the case, how can I achieve what I'm after?
I'm aware this type of storage is not scalable for thousnads of tags, I'm just tinkering with firestore for the first time and wanted to see how I would make this kind of thing work