我正在尝试建立一个应用程序,我是非常新的这一切。因此,我构建了一个非常简单的函数来从消防局获取数据,它从一开始就工作得很好。这是代码:
async getData(req, res) {
const dataRef = db.collection(`${req.body.banco}`)
let result = []
dataRef.onSnapshot(docSnapshot => {
docSnapshot.forEach(doc => {
const data = doc.data()
result.push(data)
})
console.log(result)
return res.status(200).send(result)
}, (error) => {
console.log(`Erro encontrado: ${error}`)
})
}我的问题是,当我试图从文档中更新任何字段时。它会被更新,但我最终会收到以下错误:
node:_http_outgoing:576
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at new NodeError (node:internal/errors:372:5)
at ServerResponse.setHeader (node:_http_outgoing:576:11)
at ServerResponse.header (C:\Users\paulo\Desktop\sirius-back\functions\node_modules\express\lib\response.js:794:10)
at ServerResponse.send (C:\Users\paulo\Desktop\sirius-back\functions\node_modules\express\lib\response.js:174:12)
at ServerResponse.json (C:\Users\paulo\Desktop\sirius-back\functions\node_modules\express\lib\response.js:278:15)
at ServerResponse.send (C:\Users\paulo\Desktop\sirius-back\functions\node_modules\express\lib\response.js:162:21)
at C:\Users\paulo\Desktop\sirius-back\functions\src\controller\createDocs.js:70:40
at QueryWatch.onNext (C:\Users\paulo\Desktop\sirius-back\functions\node_modules\@google-cloud\firestore\build\src\reference.js:1914:13)
at QueryWatch.pushSnapshot (C:\Users\paulo\Desktop\sirius-back\functions\node_modules\@google-cloud\firestore\build\src\watch.js:469:18)
at QueryWatch.onData (C:\Users\paulo\Desktop\sirius-back\functions\node_modules\@google-cloud\firestore\build\src\watch.js:353:26) {
code: 'ERR_HTTP_HEADERS_SENT'
}这个应用程序崩溃了,我不得不重新开始。
原因是什么?在我更新了一些东西之后,如何才能从消防局数据库获得实时更新?
发布于 2022-08-27 06:51:46
在Express中,通过向每个请求发送一个响应来处理每个请求。因为res是响应对象,所以只能向调用方发送一次响应。但是,由于您使用的是onSnapshot,所以您的代码也会在数据的每次更改中被调用。
因此,最初,您加载数据并向调用方发送响应,所有这些都是
但是,当对数据库进行更新时,您的代码将再次执行,并尝试向调用方发送另一个响应--这是当您收到一个错误时。
解决方案是只读取一个数据,其内容如下:
async getData(req, res) {
const dataRef = db.collection(`${req.body.banco}`)
let result = []
dataRef.get().then((docSnapshot) => {
docSnapshot.forEach((doc) => {
const data = doc.data()
result.push(data)
})
console.log(result)
return res.status(200).send(result)
}, (error) => {
console.log(`Erro encontrado: ${error}`)
})
}或者简化一点:
async getData(req, res) {
const dataRef = db.collection(`${req.body.banco}`)
dataRef.get().then((docSnapshot) => {
const result = docSnapshot.docs.map((doc) => doc.data());
return res.status(200).send(result)
}, (error) => {
console.log(`Erro encontrado: ${error}`)
})
}一旦您调用了res.send(...),请求就完成了,客户端停止侦听。像您使用的那样,使用Express请求/响应模型无法向响应发送进一步的更新。
另见:
您需要选择一个允许客户端持续监听的基础设施。提示:构建类似的东西是非常重要的,如果您使用客户端Firestore来实现这样的实时侦听器,您可能会更好。
https://stackoverflow.com/questions/73507128
复制相似问题