我正在使用客户端应用程序中的可调用函数,以从Firestore检索一些数据。数据使用以下方法创建:

projectData = {
  created: firebase.firestore.FieldValue.serverTimestamp(),
  ...otherData
}
firebase.firestore().collection(projectsCollection).add(projectData)

而且我可以看到时间戳正确保存在了Firestore控制台中。 callable函数还有其他功能,并且具有错误处理功能,但是数据检索是这样完成的(使用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"
      }
    }
  }
}

最佳答案

documentation:



Date is not a JSON type开始,您将必须使用自己的序列化格式(至少如果您希望它可靠/可移植)。从链接的答案看来, Date.toJSON 是一个不错的选择。

关于javascript - 云可调用函数中的返回日期/服务器时间戳,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53520674/

10-10 23:28
查看更多