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

Javascript Firebase函数的问题以及.add()与.doc().set()之间的区别,javascript,firebase,google-cloud-firestore,google-cloud-functions,Javascript,Firebase,Google Cloud Firestore,Google Cloud Functions,几周后,我面临以下问题(以前从未出现过): 1.添加(数据) 文档已成功创建,但仍有一个错误“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/l

几周后,我面临以下问题(以前从未出现过):

1.添加(数据) 文档已成功创建,但仍有一个错误“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(数据) 将
add()
替换为
doc()。set()
将创建没有任何错误的文档


知道为什么会这样吗?仅使用doc().set()的“变通方法”很简单,但我想知道为什么会有add()。我们不能对任何新文档使用doc().set()吗?

使用
set
您正在选择一个文档(您分配自己的id)并且
添加
您正在让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返回承诺应该是好的。

我发现的原因很简单明了:

add()
返回
Promise
while
set()
返回'Promise'

添加新文档的操作以任何一种方式工作,但一旦完成,响应将被发送回客户机,或者是文档引用,或者是封装在承诺中的写入结果。由于响应中只允许使用有效的JSON,因此返回文档引用将导致错误,因为它不是有效的JSON格式


因此,一旦操作完成,要么解析一个空的承诺,要么将结果转换为有效的JSON,然后再将其包装到响应中,要么使用set()。

我的第一个猜测是,将对象序列化为JSON时会出现问题,尽管这不能解释为什么它与
doc().set()一起工作。
。您的
数据中有什么?你能
console.log()
it吗?顺便说一句:如果你只需要一个节点脚本,而不需要云函数,那就太好了。在这一点上,我们可以排除许多可能的原因。函数中的
data
到底是什么?答案详细信息如下:
add()
函数返回一个承诺,与
set()
相同。最简单的方法就是使用
then
catch
向客户端返回值,甚至它也不在乎。好吧,如果你使用没有任何ID的
doc()
,它会创建一个新文档,就像.add()一样-工作非常完美,据我所知,这只是创建新文档的另一种推荐方法。那么,实际的区别在哪里呢?或者add()最终只是doc()的一个功能,实际上不需要吗?您能否更具体地说明代码/函数的外观,以便在返回所需格式的同时以相同的方式写入数据库?当然,了解数据的外观也会有很大帮助
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 })

})