我正在使用客户端应用程序中的可调用函数从Firestore检索一些数据。数据是使用以下方式创建的:
projectData = {
created: firebase.firestore.FieldValue.serverTimestamp(),
...otherData
}
firebase.firestore().collection(projectsCollection).add(projectData)
我可以看到时间戳正确地保存在了Firestore控制台中。可调用函数执行其他一些操作并具有错误处理,但是数据检索是这样完成的(使用lodash将每个文档扩展为一个对象以返回到客户端):
const projectRef = firestore.collection(gProjectsCollection).orderBy('created')
return projectRef.get().then(snapshot => {
return {
projects: _.chain(snapshot.docs)
.keyBy('id')
.mapValues(s => s.data())
.value()
}
})
这通常可以正常工作,但是返回的对象具有一个损坏的created
属性(如此处在函数shell输出中所示):
RESPONSE RECEIVED FROM FUNCTION: 200, {
"result": {
"projects": {
"XcRyQyaxLguRdbNmxQdn": {
"name": "c",
"description": "c",
"created": {
"_seconds": 1543405587,
"_nanoseconds": 169000000
}
}
}
}
}
我认为这是因为可调用函数在内部使用JSON.stringify()
,并且服务器时间戳未正确转换。我尝试将时间戳明确转换为这样的日期:
return projectRef.get().then(snapshot => {
return {
exVersion,
exId,
projects: _.chain(snapshot.docs)
.keyBy('id')
.mapValues(s => s.data())
.forEach(d => { d.created = d.created.toDate() })
.value()
}
})
但是现在我得到了一个空对象:
RESPONSE RECEIVED FROM FUNCTION: 200, {
"result": {
"projects": {
"XcRyQyaxLguRdbNmxQdn": {
"name": "c",
"description": "c",
"created": {}
}
}
}
}
我怀疑这里的真正问题是可调用函数未设置为返回日期对象。如果再走一步并将时间戳记转换为字符串,那么我最终会在客户端获得一些信息:
return projectRef.get().then(snapshot => {
return {
exVersion,
exId,
projects: _.chain(snapshot.docs)
.keyBy('id')
.mapValues(s => s.data())
.forEach(d => { d.created = d.created.toDate().toISOString() })
.value()
}
})
给予:
RESPONSE RECEIVED FROM FUNCTION: 200, {
"result": {
"exVersion": 9,
"exId": null,
"projects": {
"XcRyQyaxLguRdbNmxQdn": {
"name": "c",
"description": "c",
"created": "2018-11-28T11:46:27.169Z"
}
}
}
}
我在可调用函数的文档中找不到关于日期的特殊处理的任何内容,但是在执行该操作的方式上我是否有所遗漏?
可调用函数中的一些进一步分析表明涉及JSON.stringify()
,但并不是全部问题:
console.log(JSON.stringify(d.created)):
info: {"_seconds":1543405587,"_nanoseconds":169000000}
JSON.stringify(d.created.toDate())
into: "2018-11-28T11:46:27.169Z"
因此,调用d.created.toDate()
应该就足够了。但是我还有其他情况,其中Date
对象不是可调用函数返回的,例如:
const testObject = {
some: 'thing',
d: new Date()
}
console.log('JSON:', JSON.stringify(testObject))
return projectRef.get().then(snapshot => {
return {
testObject,
projects: _.chain(snapshot.docs)
.keyBy('id')
.mapValues(s => s.data())
.forEach(d => { console.log('d.created is:', JSON.stringify(d.created.toDate())); d.created = d.created.toDate() })
.value()
}
})
请注意,在下面的输出中,日期对象上JSON.stringify()
的记录结果似乎有效,但是当这些对象包含在从函数返回的对象中时,它们都以空对象的形式出现:
firebase > getAllProjects({uid: 1234})
Sent request to function.
firebase > info: User function triggered, starting execution
info: JSON: {"some":"thing","d":"2018-11-28T13:22:36.841Z"}
info: Got 1 projects
info: d.created is: "2018-11-28T11:46:27.169Z"
info: Execution took 927 ms, user function completed successfully
RESPONSE RECEIVED FROM FUNCTION: 200, {
"result": {
"testObject": {
"some": "thing",
"d": {}
},
"projects": {
"XcRyQyaxLguRdbNmxQdn": {
"description": "c",
"created": {},
"name": "c"
}
}
}
}
答案 0 :(得分:2)
要将数据发送回客户端,请返回可以JSON编码的数据。
自Date
is not a JSON type起,您将必须使用自己的序列化格式(至少如果您希望它可靠/可移植)。从链接的答案来看,Date.toJSON
似乎是一个很好的选择。