firebase-functions: Receiving exception of stackoverflow by lodash from simple queries on onCall but not onRequest
from package.json:
"firebase-admin": "~5.12.1",
"firebase-functions": "^1.0.3",
"mysql2": "^1.5.3",
"sequelize": "^4.37.10"
And using this code:
const models = require('./db/models');
const throw_db_issue = e => {
throw new functions.https.HttpsError('failed-db-issue', `DB issue: ${e.message}`);
};
exports.all_categories = functions.https.onCall((data, context) => {
return models.Category.findAll({
where: { parent_id: null },
include: ['children', models.CategoryImage],
}).catch(throw_db_issue);
});
Where models is defined as:
const Sequelize = require('sequelize');
const CategoryImage = sequelize.define(
'category_images',
{
category_id: Sequelize.INTEGER,
image_path: Sequelize.STRING,
},
{
underscored: true,
}
);
const Category = sequelize.define(
'categories',
{
name: Sequelize.STRING,
parent_id: Sequelize.INTEGER,
},
{
underscored: true,
}
);
CategoryImage.belongsTo(Category);
Category.hasOne(CategoryImage);
And I get this stack trace in firebase console:
Unhandled error RangeError: Maximum call stack size exceeded
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)
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)
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)
But this is fine if I run this code as under plain onRequest
.
Please fix/suggest solution as I prefer onCall
to onRequest
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 17 (8 by maintainers)
Hi. This error occurs when your callable function returns an object that has cycle within it.
In @diegogarciar’s case, the issue is that the function is returning the result of the call to
userGroupsRef.once
, which is aDataSnapshot
. I suspect that instead of this:you probably meant to write this:
The snapshot is the same either way, but if you want to chain the promises so that everything runs before the function completes (and you do), you have to do the latter.
In @fxfactorial’s case, it looks like it’s returning an array of sequelize
Model
s. I’m assuming that object has some cycle in it. I’m not sure what the best fix there would be. If you could transform eachModel
into a plain JavaScript object with just the fields you care about, that would fix it. Maybe instead of this:you could do this:
Thanks, @Danebrouwer97. That’s an interesting point. We should consider whether we can support
toJSON
on objects that have them without breaking the custom formatting for certain types.Thanks for the speedy response,
Just an additional note: I see in the encoding source file, that it uses the following code when dealing with an object.
However, using this method ignores any custom toJSON methods that are usually called when ‘stringifying’ the object.
This is the source of the issue in using Sequelize and returning an instance/instances of a model from firebase. An instance of a model has recursion and its custom toJSON method normally removes that, this can be easily tested by returning the ‘stringified’ instance from a firebase function.
The easiest solution that I can see is to just update the error with a more intuitive output, perhaps even mention the fact that firebase’s encoding method ignores any custom toJSON method.
Glad to hear 😃 thanks for closing. As always, feel free to open another issue if you encounter any other problems!
yes, thank you!
as @bklimt suggester using .then() as
return userGroupsRef.once("value").then(snapshot =>{ })
solved the issue perfectly, I adopted the syntax everywhere else. Thanks by the way @bklimt