Firebase函数问题以及.add()与.doc()。set()之间的区别

时间:2019-06-12 12:39:49

标签: javascript firebase google-cloud-firestore google-cloud-functions

几个星期以来,我遇到了以下问题(以前不是问题):

1 .add(data)

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

文档已成功创建,但仍然向客户端返回错误“ INTERNAL”,并在功能日志中列出:

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)

add()替换doc().set()可以创建文档而没有任何错误。

知道为什么会这样吗?仅使用doc()。set()即可轻松实现“变通方法”,但我不知道为什么还要添加()。我们不能只对任何新文档使用doc()。set()吗?

2 个答案:

答案 0 :(得分:0)

使用set,您选择一个文档(分配自己的ID),add,您让Firestore为您分配ID。

这里有一个很小的(不是那么小的)细节,您的可调用函数应返回一个承诺,该承诺将与响应一起解析以发送给客户端,您的函数将返回一个对数据库进行操作后已解决的承诺。

您的代码抱怨的那一行看起来像这样:

if (_.isArray(data)) {
  return _.map(data, encode);
}

与您使用的方法相比,我将更加关注发送的数据。

const saveNewDoc = functions.https.onCall(async (data: NewDocWrite, context: CallableContext) => {
  await adminDb.collection(data.collectionPath).add(data.data)
  // OR
  await adminDb.collection(data.collectionPath).doc().set(data.data)
  return Promise.resolve({ ok: true })

})

实际上,doc().set()等效于.add(),我通常使用set,因为我希望可以控制要设置的文档ID,但也可以将其保留为空。尝试这样做,避免对数据库exec返回promise应该很好。

答案 1 :(得分:0)

我发现的原因很简单:

add()返回Promise<FirebaseFirestore.DocumentReference>的同时 set()返回“承诺”

添加新文档的操作可以以任何一种方式进行,但是一旦完成,响应就会被发送回客户端,文档引用或写在Promise中的结果都将返回给客户端。由于响应中仅允许使用有效的JSON,因此返回文档引用将导致错误,因为该引用不是有效的JSON格式。

因此,一旦操作完成,请解析一个空的Promise或将结果转换为有效的JSON,然后再将其包装在响应中-或使用set()。