问题
after several Q&A about the transaction mechanism I'm trying to run a transaction on a lowel node
here is my data:
activeOffers
-LKohyZ58cnzn0vCnt9p
details
direction: "city"
seatsCount: 2
timeToGo: 5
uid: "-ABSIFJ0vCnt9p8387a" ---- offering user
I'm trying to run the transaction on -LKohyZ58cnzn0vCnt9p and do the following:
- decrease the seatsCount by some requested value if there is enought seats
- add a subnode deal under ** -LKohyZ58cnzn0vCnt9p** with the requested value and the uid of the requesting user.
But obviously I don't do it correctly because I get Maximum call stack size exceeded even only for step 1.
Here is my code:
(entryRef is the ref to -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;
});
}
================ update after Frank van Puffelen's comment ===============
I don't see any recursion in my flow:
I call the cloud function in Postman sending the following data:
{
"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);
});
===== entries.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 + ']';
}
});
}
and here is the stacktrace in the error log:
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)
I don't have any triggers or something that could call again and again the same code...
回答1:
And finally it appeared to be very very stupid of me. If I wanted to use transaction returning a promise I should put
.then((success)=>{ ... }
after the transaction. i.e.:
return entryRef.transaction((current)=>{
if (current) {
if (current.details.seatsCount >= data.details.seatsCount) {
current.details.seatsCount -= data.details.seatsCount;
}
}
return current;
})
.then((success)=> {
.......
});
And everything is fine now :)
来源:https://stackoverflow.com/questions/52043552/firebase-transaction-on-lower-node-maximum-call-stack-size-exceeded