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.