Wiingaard
Wiingaard

Reputation: 4302

Firebase function error; "Maximum call stack size exceeded"

I've made a function that toggles a boolean value in the database via a transaction. Take a look:

export const toggleDoneState = functions.https.onCall((data, context) => {
    const userId = getUserIdFromCallableContext(context)
    let togglePath: admin.database.Reference

    if (!isUndefined(data.subtaskId)) {
        const subtaskId = data.subtaskId
        if (isValidString(subtaskId)) {
            togglePath = admin.database().ref("userSubtasks").child(userId).child(subtaskId).child("done")
        } else {
            throw new functions.https.HttpsError('invalid-argument', 'Expected valid Subtask Id')
        }
    } else {
        throw new functions.https.HttpsError('invalid-argument', 'Expected valid toggle type')
    }

    return togglePath.transaction(currentValue => {
        return !(currentValue || false)
    }).then(value => { 
        return { done: value }
    })
})

This is the only function I have deployed! I used to have about 15 functions running, but I've removed them to make this test cleaner.

When I call the function from an iOS app, I see that the value in the database is toggled as expected, but I receive an error from the Functions SDK in iOS:

Domain=com.firebase.functions Code=13 "INTERNAL" UserInfo={NSLocalizedDescription=INTERNAL}

When I look at the functions logs in the console I see the following error:

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)

The value in the database is toggled as expected, but I would like to not get and error and understand why. Any clues?

Upvotes: 1

Views: 2556

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317692

I suspect you have a misunderstanding about what value is in the then callback after your transaction. If you look at the API docs for transaction(), you'll see that it returns a promise that contains a couple properties, one of which is a DataSnapshot. You're effectively trying to serialize that DataSnapshot object, and I think that lodash is encountering a problem with that, maybe a circular reference.

First of all, try fixing the return value of your then callback and see if that clears things up. Then, figure out how to use the DataSnapshot yielded by the transaction to return to the client the value you intend.

Upvotes: 1

Related Questions