How to push to a child node while updating values in the parent node Firebase RealTime

Tags: , , ,



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"
          }
    }
}

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.



Source: stackoverflow