这是我的数据结构,如何组织(firebase数据库):
-database
-productsList
-item1: 0
-item2: 0
-item3: 0
-item4: 0
-orders
-order1:
-...
-order2:
-...
-...
我正在构建一个包含产品列表的购物应用程序。客户可以选择要购买的商品并下订单。当他们这样做时,产品的数量将根据他们选择的数量而增加。 假设某客户选择购买2单位的item2和5单位的item4,当一个客户发送请求时,它将在不同的位置写入以下数据:
-orders
-orderKey
-items
-item2: 2
-item4: 5
然后,列表将更新为(基于onCreate方法):
-productsList
-item1: 0
-item2: 2
-item3: 0
-item4: 5
但是,让我们假设另一个客户同时提出了一个请求,产品列表必须承认这一点。
我很了解firebase交易,因此必须执行 作为交易而不是更新。 但是,在此处进行彻底搜索的所有示例仅显示了如何更新单个节点而不是多个子节点。
我正在使用云函数来完成此操作,这意味着我正在使用打字稿。
使用事务更新多个子级的最佳方法是什么?
怎么可能只获得并增加所需的节点?
请,我们将不胜感激。
编辑:Frank van Puffelen回答了我的问题后,我决定更清楚地说明我需要做的事情。
我只希望更新名为 productsList 的一个节点,在此示例中,其子节点 item2 和 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
}
答案 0 :(得分:0)
事务在JSON树中的单个节点上运行,但是它们可以在树中的任何节点上运行。
这意味着,如果需要以事务方式更新多个节点,则需要在这些节点的共同祖先处运行事务。因此,如果您需要同时更新orders
和productsList
下的数据,则需要在它们的共同祖先运行事务。
请记住:
一种选择是使用多位置更新。与事务不同,多位置更新不会读取整个公共祖先的值,并且不会自动重试。
这种方法要考虑的一些缺点/事情:
有关此方法的更多信息,请在这里查看我的答案:Is the way the Firebase database quickstart handles counts secure?
我能想到的最后一种选择是在可控制并行性的受信任环境中运行此代码。例如,假设您在常规节点进程中运行它,那么您可以确保只有一个实例在运行。然后,如果您还确保只有该(管理)过程可以更新这些值,则不需要事务处理就可以进行更新,并且可以更好地进行扩展。