错误 [ERR_HTTP_HEADERS_SENT]:使用 Firebase 将它们发送到客户端 NodeJS 后无法设置 headers

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client NodeJS with Firebase

描述
每次我包含 response.send(snapshot.val()); 时都会发生此错误并且 NodeJS 服务器崩溃。我正在使用 Postman 测试 API 端点和 Header 它工作正常。

输出

On terminal 401 Unauthorized 

[2020-11-05T13:23:24.421Z]  @firebase/database: FIREBASE WARNING: Exception was thrown by user callback. Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

NodeJS

const getsRoute = require('./routes/gets');
app.use('/api/v1', getsRoute);

//on other file
const auth = require('../middleware/auth');
router.get('/products', auth, (req, res) => {
    initialPage.getBusinesses(res);
});

产生错误的代码

const initialPage = {
    getBusinesses(response) {
        ref.orderByKey()
        .limitToLast(20)
        .on('value', function(snapshot){
            response.json(snapshot.val()); 
            return snapshot.val();
        })
    }
}

客户端使用 React Native

  searchApi = async() => {
        const response = await axios.get('http://33c75838823c90.ngrok.io/api/v1/products',{
                headers: {
                    "Content-Type": "application/json",
                    "Accept": "application/json",
                    "x-auth-token":"jgiiHDgfdeizI1NiIJ9.eyJfaWQiOiI1ZmEwMWMzZmM4YjIwYjBjZDQyMmJkNzUiLCJpYXQiOjE2MDQ0MTAwMDZ0KwFAgVtsJUQw"
                }
            }
        ).catch((error) => {
            console.log("ERROR FROM AXIOS:", error)
          });
        console.log("RESPONSE DATA: %%%%%%%", response.data)
        this.setState({results: [response.data]});
       
    }

我查了很多文档和问题论坛,但没有人得到完全适合一般问题的解决方案。

问题在这里:

getBusinesses(response) {
    ref.orderByKey()
    .limitToLast(20)
    .on('value', function(snapshot){
        response.json(snapshot.val()); 
        return snapshot.val();
    })
}

由于您使用的是 on(...),您的回调将被调用:

  1. 数据一加载,
  2. 之后,任何时候数据发生变化。

第一个按预期工作,但如果数据发生变化,这意味着您正在尝试发送另一个响应,这就是导致错误的原因。

要解决此问题,请使用 once 而不是 on

getBusinesses(response) {
    ref.orderByKey()
    .limitToLast(20)
    .once('value', function(snapshot){
        response.json(snapshot.val()); 
        return snapshot.val();
    })
}