执行Firebase交易时如何检查节点的值?

时间:2018-07-13 18:36:45

标签: javascript node.js firebase firebase-realtime-database

我正在特定位置运行Firebase事务,但是在更新它之前,我需要确保它不大于特定数目。如何在Node.JS中执行此操作?我当前的代码不起作用。

我尝试输入的代码:

var reward_count_red_ref = admin
  .database()
  .ref("Rewards/" + Artcall_ID + "/" + reward_id + "/rewards_left");

reward_count_red_ref
  .transaction(current => {
    const increment = -1 * ticket_count;
    console.log("Going to check if tickets are available");

    if (ticket_count > current) {
      console.log("Tickets not available. The current value is:", current);
    } else {
      return (current || 0) + increment;
      console.log("They are available. The current value is:  ", current);
    }
  })
  .then(() => {
    console.log("Tickets updated.");
    admin
      .database()
      .ref(
        "/Reserve_Project_Request/" + Artcall_ID + "/" + User_ID + "/Response"
      )
      .set("success");
  });

2 个答案:

答案 0 :(得分:2)

您编写的代码缺少一些成分,可以帮助您调试问题并使其正常运行。

事务返回带有两个参数的对象:{ committed, snapshot }。请务必检查committed布尔值,以查看事务是否确实更改了某些内容。对于您来说,如果committedfalse,则您想通知用户票证不可用。

还请注意,current可能是null(并且将在事务的大多数首次运行中使用)。您可能希望以不同的方式处理这种情况,并检查snapshot.exists()

缺少的另一件事是catch子句。您的交易很可能失败了。如果是这样,您可能会丢失它。这也是返回.set(...)调用以确保您也捕获到该结果的好计划。

可能出错的另一件事是,其他一些代码正在使用setupdate修改该位置的数据。如果发生这种情况,交易将被取消。

对于事务本身中的代码,看起来还可以。 current || 0虽然没有多大意义。如果current是null并且ticket_count是一个正数(我认为您应该在另一个地方对此保持警惕),它将永远不会到达此分支。

我个人将(current || 0) + increment更改为current - ticket_count,以使其更具可读性,但这只是味道。


更新

您可以像这样访问committedsnapshot

ref.transaction(...).then(({ committed, snapshot }) => ...)

如果您想重试失败的事务,可以使用如下函数:

async function withRetries(ref, transaction, attempts = 0) {
  try {
    const result = await ref.transaction(transaction, undefined, false)
    return result
  } catch (e) {
    if (attempts < MAX_TRANSACTION_ATTEMPTS) return withRetries(ref, transaction, attempts + 1)
    throw new Error(`transaction failed ${MAX_TRANSACTION_ATTEMPTS} times, error: ${e.message}`)
  }
}

答案 1 :(得分:0)

只需将条件添加到current

  if (current > value) {
    return { name: { first: 'Ada', last: 'Lovelace' } };
  } else {
    return; // Abort the transaction.
  }