Reputation: 4302
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
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