【问题标题】:Firebase transaction completes with null value and no errorsFirebase 事务以空值完成且没有错误
【发布时间】:2021-11-14 05:40:01
【问题描述】:

这个问题有点类似于Firebase transaction returns null and completes without error。不过,我已经有了建议的解决方案。

以下使用 Firebase web 版本 9。在节点 v14.17.3 中运行

const returnVal = await runTransaction(firebaseRef, async node => {
  console.log("1", node);
  if (node && node.ready != true) {
    node.ready = true;
  }
  console.log("2", node);
  return node;
});
if (!returnVal.committed) throw new Error("Not committed");
console.log("3", returnVal.snapshot.toJSON());

在你继续说之前,我没有将节点设置为空对象,我希望它稍后会成为一个对象。

这是我的输出。

1 null
2 null
1 {otherMeta: {…}}
2 {otherMeta: {…}, ready: true}
3 null

如您所见,交易以空值完成。这很奇怪。

【问题讨论】:

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


    【解决方案1】:

    TL;DR:只需删除 async 关键字即可。

    弗兰克把它钉在了头上,但我要写下一个单独的答案,以便我可以使用语法突出显示。如果你有两个相同的功能:

    function theAnswer() { return 42; }
    async function theEventualAnswer() { return 42; }
    

    这两个函数的行为非常不同。第一个返回文字42。第二个实际上返回Promise.resolve(42)。如果你尝试添加theAnswer() + 1,你会得到43。如果你尝试添加theEventualAnswer() + 1,你会得到'[object Promise]1'

    在这种情况下,您返回了 Promise.resolve({...node, ready: true}),SDK 稍后将 tries to turn into a Reference 得到了一些非常奇怪的结果,因为它需要具体类型。

    我已代表您提交了a bug,详细说明了团队如何为您提供编译时错误消息。

    【讨论】:

    • 是你抓住了多余的async关键字。我只是一个健谈的人,他把这个变成了一个完整的答案和错误报告。
    • 我会将此标记为路过的疲惫旅行者的答案。我仍然认为异步是回调的更好方法,其中可以为提交解决承诺,并为取消事务而拒绝,而不是必须返回未定义的。
    【解决方案2】:

    当我注意到这似乎来自 async 关键字时,我正要针对 SDK 提交回归错误。

    如果我使用此代码:

    runTransaction(firebaseRef, async (node) => {
      console.log("1", node);
      if (node && node.ready != true) {
        node.ready = true;
      }
      console.log("2", node);
      return node;
    }).then((result) => {
      if (!result.committed) throw new Error("Not committed");
      console.log("3", result.snapshot.toJSON());
    });
    

    我得到最后一个日志的输出为:

    3 空

    当我删除 only async 关键字(无论如何都不需要)时,我得到:

    3 {a: true, ready: true}

    我的测试台:https://stackblitz.com/edit/firebase-v9-rtdb

    我不知道async 关键字可能是什么原因造成的。虽然如前所述,该关键字在我的 sn-p 中是不必要的,但在您的代码中却是必需的,我看不出它会如何影响结果。

    【讨论】:

    • 我需要异步回调,让事务异步运行更有意义,其中可以拒绝或解决承诺以提交或失败事务。无论如何,看起来我将不得不找到一个解决方法。谢谢!
    猜你喜欢
    • 2018-10-11
    • 2019-12-31
    • 1970-01-01
    • 2018-10-25
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    相关资源
    最近更新 更多