较低节点上的Firebase事务-超出最大调用堆栈大小

时间:2018-08-27 16:34:56

标签: javascript firebase firebase-realtime-database transactions

在对事务处理机制进行了几次问答之后,我试图在低级节点上运行事务

这是我的数据:

activeOffers
    -LKohyZ58cnzn0vCnt9p
        details
            direction: "city"
            seatsCount: 2
            timeToGo: 5
        uid: "-ABSIFJ0vCnt9p8387a"    ---- offering user

我正在尝试在 -LKohyZ58cnzn0vCnt9p 上运行事务,并执行以下操作:

  1. 将座位数减少一些要求的值如果座位不足
  2. 在** -LKohyZ58cnzn0vCnt9p **下添加带有请求值和请求用户uid的子节点交易。

但是很明显我做错了,因为即使在第1步中,我仍然达到最大调用堆栈大小

这是我的代码:

entryRef 是对 -LKohyZ58cnzn0vCnt9p 的引用)

dealSeats = function(entryRef, data) {
    const TAG = '[dealSeats]: ';
    return entryRef.transaction((current)=>{
        if (current) {
            if (current.details.seatsCount >= data.details.seatsCount) {
                current.details.seatsCount -= data.details.seatsCount;
            }
        }
        return current;
    });
}

================在Frank van Puffelen评论后==============

后更新>

我的流程中没有任何递归:

我在Postman中调用cloud函数发送以下数据:

{
 "data": 
  {
     "uid": "-FGKKSDFGK12387sddd",    ---- the requesting/asking user
     "id": "-LKpCACQlL25XTWJ0OV_",
     "details":
     {
          "direction": "city",
          "seatsCount": 1,
          "timeToGo": 5
     }
  }
}

===== index.js =====

entries = require('./entries');

/// cloud function
exports.TEST_askOfferSeats = functions.https.onCall((data, context) => {
    console.log('data: ' + JSON.stringify(data));
    return entries.askSeats(data);
});

===== entry.js =======

exports.askSeats = function(data) {
    const TAG = '[askSeats]: ';

    var entryRef = db.ref('activeOffers/' + data.id);
    return globals.exists(entryRef)
        .then((found)=>{
            if (found) {
                return dealSeats(entryRef, data);
            } else {
                return 'Offer not found [' + data.id + ']';
            }
        });
}

这是错误日志中的堆栈跟踪:

function:
  TEST_askOfferSeats
event message:
  Unhandled error RangeError: Maximum call stack size exceeded
      at Function.mapValues (/user_code/node_modules/firebase- 
  functions/node_modules/lodash/lodash.js:13395:23)
      at encode (/user_code/node_modules/firebase- 
  functions/lib/providers/https.js:204:18)
      at /user_code/node_modules/firebase- 
  functions/node_modules/lodash/lodash.js:13400:38
      at /user_code/node_modules/firebase- 
  functions/node_modules/lodash/lodash.js:4925:15
      at baseForOwn (/user_code/node_modules/firebase- 
  functions/node_modules/lodash/lodash.js:3010:24)
      at Function.mapValues (/user_code/node_modules/firebase- 
  functions/node_modules/lodash/lodash.js:13399:7)
      at encode (/user_code/node_modules/firebase- 
  functions/lib/providers/https.js:204:18)
      at /user_code/node_modules/firebase- 
  functions/node_modules/lodash/lodash.js:13400:38
      at /user_code/node_modules/firebase- 
  functions/node_modules/lodash/lodash.js:4925:15
      at baseForOwn (/user_code/node_modules/firebase- 
  functions/node_modules/lodash/lodash.js:3010:24)
      at Function.mapValues (/user_code/node_modules/firebase-         
  functions/node_modules/lodash/lodash.js:13399:7)

我没有任何触发器或可以反复调用相同代码的东西...

1 个答案:

答案 0 :(得分:0)

最后,这似乎让我非常愚蠢。 如果我想使用交易返回承诺,我应该提出

  .then((success)=>{   ...   }

交易后。即:

 return entryRef.transaction((current)=>{
    if (current) {
        if (current.details.seatsCount >= data.details.seatsCount) {
            current.details.seatsCount -= data.details.seatsCount;
        }
    }
    return current;
})
.then((success)=> {
.......
});

现在一切都很好:)