如何使用交易来更新子节点下的多个孩子



这是我的数据结构,如何组织(firebase数据库):

 -database
  -productsList
    -item1: 0
    -item2: 0
    -item3: 0
    -item4: 0
  -orders
    -order1:
      -...
    -order2:
      -...
    -...

我正在构建一个具有产品列表的购物应用程序。客户可以选择他们想购买的商品并下订单。当他们进行产品数量时,将根据所选择的东西增加。说客户选择购买2个项目2 E 5单位的项目4,当一个人发送请求时,它将在其他位置写入以下数据,例如:

-orders
 -orderKey
  -items
   -item2: 2
   -item4: 5

然后,列表将更新为(基于ongreate方法):

-productsList
 -item1: 0
 -item2: 2
 -item3: 0
 -item4: 5

但是,假设另一个客户同时提出了请求,则产品列表必须确认这一点。

我很清楚燃烧案交易,必须实施作为交易而不是更新。但是,在这里彻底搜索的所有示例都只显示了如何更新单个节点而不是多个孩子。

我正在使用云功能来实现这一目标,这意味着我正在使用Typescript。

使用交易更新多个孩子的最佳方法是什么?

如何仅获取和增加所需的节点?

请,任何帮助都将不胜感激。


编辑:弗兰克·范·普菲伦(Frank Van Puffelen)回答我的问题后,我决定更清楚地说明我需要做什么。

我只想更新一个节点 node productsList and,在此示例中,其子节点 item2 and strong> and child4

这是一些更好地说明它的代码:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase)
export const onOrderCreate = functions.database
.ref('/orders/{oid}')
.onCreate(async (snapshot, context) => {
    const orderId = context.params.oid
    console.log(`new order made: ${oid}`)
    const orderData = snapshot.val()
    const items = getProductsAndQuantities(orderData)
    const path = 'productsList'
    return admin.database().ref(path).transaction(items => {
        // I would like to know if there's a way to update only the bought items, like
        const updatedList = {
            'item2': item2oldValue + 2,
            'item4': item2oldValue + 5 
        }
        return updatedList
    })
})
// Get the order data and return only the items and its quantities
function getProductsAndQuantities(data: any): Object {
    // Return items, exemple
    const products = {
        'item2': 2,
        'item4': 5 
    }
    return products
}

交易在JSON树中的单个节点上运行,但它们可以在该树中的任何节点上运行。

这意味着,如果您需要进行交易更新多个节点,则需要在这些节点的共同祖先上运行交易。因此,如果您需要在ordersproductsList下更新数据,则需要在这些祖先的共同祖先进行交易。

请记住:

  • 交易首先在位置读取值,然后将其返回给您的客户。这意味着您的事务运行的树中的越高,您将使用的带宽越多。
  • 如果另一个客户更改了读取和写入之间的数据,则
  • 交易将自动重新进行。在更高级别的位置上执行此操作,使交易更有可能是在争夺交易的可能性,即,多个客户正在同时更新该位置下的数据。

一种替代方法是使用多站点更新。与交易不同,多站点更新不会读取整个共同祖先的价值,也不会自动退缩。

在这种方法中要考虑的一些缺点/事物:

  • 如果新值取决于现有值,则您仍然必须自己读取值。但是,超过交易的优势在于,您可以阅读要更新的精确值,而不是阅读整个共同祖先。
  • 多站点更新,只是更新,这意味着它们没有检测到相互矛盾的更新的机制。这是您可以在安全规则中实施的东西,但绝对远非微不足道。
  • 多站点更新不会自动重新返回,因此,如果安全规则拒绝更新(例如:如果另一个客户端仅更新相同的值),则必须在客户端代码中自己处理该更新。

有关此方法的更多信息,请参见我的答案:Firebase数据库QuickStart处理计数安全吗?


我能想到的最终替代方法是在您控制并行性的可信环境中运行此代码。例如,例如,您在常规节点过程中运行它,然后可以确保该进程运行的一个实例。而且,如果您还确保只有此(管理)过程才能更新这些值,则不需要交易来进行更新,并且情况会更好地扩展。

最新更新