I am trying to update the values in the parent node of a firebase realtime db while simultaneously pushing data to a child node, however I get the error “Reference.update failed: First argument contains a path /xyz that is ancestor of another path /xyz/…/…”
const updatedPosition = { category: values.category, shares: newShares, cost: newCost, } let updates = {} const newTransactionKey = docRef.child('transactions').push().key; updates[ticker + '/transactions/' + newTransactionKey] ={ date: new Date().toString(), transaction: `${Number(values.shares)} shares added @ $${perShare} ea` } updates[ticker] = updatedPosition; let updateSuccess = true; await docRef.update(updates, (error) => { console.log(error); if (error){ updateSuccess = false; } });
And my data is structured as so:
parentNode: { category: "string", shares: "number", cost: "number", transactions: { 0:{ date: DateString, type: "string" } } }
Advertisement
Answer
Your updates
contains these two keys:
${ticker}/transactions/${newTransactionKey} ${ticker}
It helps to realize that the Realtime Database processes a multi-location update as a list of set
statements. So the first line sets a value to a deep key under ${ticker}
, and then the second line sets a value to ${ticker}
.
This means the second key will completely overwrite the first key. Since this is always the case, it is a programming error, and the database rejects it.
If you want to update category
, shares
and cost
under the update too, you’ll need to add them separately:
let updates = {} const newTransactionKey = docRef.child('transactions').push().key; updates[`${ticker}/transactions/${newTransactionKey}`] ={ date: new Date().toString(), transaction: `${Number(values.shares)} shares added @ $${perShare} ea` } updates[`${ticker}/category`] = values.category; updates[`${ticker}/shares`] = newShares; updates[`${ticker}/cost`] = newCost;
Now there are 4 individual updates under ${ticker}
and none of them overlap with another.