Ad

Firebase Functions Issue And The Difference Between .add() Vs. .doc().set()

I face the following issue since a few weeks (hasn't been an issue before):

1 .add(data)

const saveNewDoc = functions.https.onCall((data: NewDocWrite, context: CallableContext) => {
  return adminDb
    .collection(data.collectionPath)
    .add(data.data)
})

Document gets successfully created but there's still an error "INTERNAL" returned to the client and also listed in the functions log:

Unhandled error RangeError: Maximum call stack size exceeded
    at baseIteratee (/srv/node_modules/lodash/lodash.js:3464:26)
    at getIteratee (/srv/node_modules/lodash/lodash.js:5932:33)
    at Function.map (/srv/node_modules/lodash/lodash.js:9556:31)
    at encode (/srv/node_modules/firebase-functions/lib/providers/https.js:236:18)
    at /srv/node_modules/lodash/lodash.js:13402:38
    at /srv/node_modules/lodash/lodash.js:4911:15
    at baseForOwn (/srv/node_modules/lodash/lodash.js:2996:24)
    at Function.mapValues (/srv/node_modules/lodash/lodash.js:13401:7)
    at encode (/srv/node_modules/firebase-functions/lib/providers/https.js:242:18)
    at /srv/node_modules/lodash/lodash.js:13402:38

2 .doc().set(data)

Replacing add() by doc().set() creates the document without any errors.

Any idea why this happens? The "workaround" is simple just using doc().set() but I wonder why there even is the add() then. Can't we just use doc().set() for any new document?

Ad

Answer

The reason I've found is simple and clear cut:

add() returns Promise<FirebaseFirestore.DocumentReference> while set() returns `Promise

The operation of adding a new document works in either way but once done, the response is sent back to the client, either the document reference or the write result wrapped in a promise. As there is only valid JSON allowed in the response, returning a document reference will result in an error, because it is not in a valid JSON format.

So once the operation is done, either resolve an empty Promise or transform the result into valid JSON before wrapping it in the response - or use set().

Ad
source: stackoverflow.com
Ad