Error: Can't set headers after they are sent a

2020-02-16 04:20发布

问题:

There are a lot of question with my issue but, I tried some of the solution and no one worked.

I'm getting the following error everytime I tried to do the login:

Error: Can't set headers after they are sent. at validateHeader (_http_outgoing.js:491:11) at ServerResponse.setHeader (_http_outgoing.js:498:3) at ServerResponse.header (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/express/lib/response.js:767:10) at userService.checkUser (/home/ale/PycharmProjects/veople/webapp/functions/index.js:54:18) at Object.firebase.auth.onAuthStateChanged.firebaseUser [as next] (/home/ale/PycharmProjects/veople/webapp/functions/auth.js:69:17) at /home/ale/PycharmProjects/veople/node_modules/@firebase/util/dist/index.node.cjs.js:1361:22 at /home/ale/PycharmProjects/veople/node_modules/@firebase/util/dist/index.node.cjs.js:1465:21 at at process._tickCallback (internal/process/next_tick.js:189:7)

this is my index.js in node:

app.get('/user', (request, response) => {
    userService.checkUser( (firebaseUser) => {
        if (firebaseUser) {
            response.render('user', {firebaseUser});
        }else {
            // response.redirect('/');
            response.redirect('/');
        }
        response.set('Cache-Control', 'public, max-age=300, s-maxage=600');
        response.render('index');
    });

});


app.post("/login", (req, res) => {
 var userEmail = req.body.emailLogin;
 var userPassword = req.body.passwordLogin;
 console.log(userEmail, userPassword); //This log the email and the password

 userService.loginUser(
   userEmail,
   userPassword,

   (error, authData) => {
     if (error) {
       return res.status(401).send("Unauthorized");
     } else {
       res.redirect('/user');
       //console.log(authData);
       return authData
     }
   }
 );
});

and in auth.js I have :

function loginUser(email, password, callback) {
     console.log(email, password);
     firebase
       .auth()
       .signInWithEmailAndPassword(email, password)
       .then((firebaseUser) => {
         // Success
         console.log("Ok, lovely I'm logged");
         callback(null, firebaseUser);
         //console.log(firebaseUser);
         return firebaseUser
       })
       .catch((error) => {

         callback(error);
       });
   }


function checkUser( callback ) {
   firebase
       .auth()
       .onAuthStateChanged(firebaseUser => {
           if(firebaseUser) {
               // console.log(firebaseUser);
               callback(firebaseUser);
               return firebaseUser;
           } else {
               console.log('pp');
               callback(null);
               return firebaseUser;
           }

       });
}

So far if I run the server on my machine, the login works but I get anyway the error in my log, instead, if I deploy my project on firebase I can't use the login function.

Probably the problem is this error.

Can anyone explain me what I'm doing wrong? Thankyou

EDIT

After aplying the @molda solution I'm getting:

error: Error: Can't set headers after they are sent. at validateHeader (_http_outgoing.js:491:11) at ServerResponse.setHeader (_http_outgoing.js:498:3) at ServerResponse.header (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/express/lib/response.js:767:10) at ServerResponse.location (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/express/lib/response.js:884:15) at ServerResponse.redirect (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/express/lib/response.js:922:18) at userService.checkUser (/home/ale/PycharmProjects/veople/webapp/functions/index.js:51:22) at Object.firebase.auth.onAuthStateChanged.firebaseUser [as next] (/home/ale/PycharmProjects/veople/webapp/functions/auth.js:73:17) at /home/ale/PycharmProjects/veople/node_modules/@firebase/util/dist/index.node.cjs.js:1361:22 at /home/ale/PycharmProjects/veople/node_modules/@firebase/util/dist/index.node.cjs.js:1465:21 at at process._tickCallback (internal/process/next_tick.js:189:7) 127.0.0.1 - - [06/Apr/2019:10:54:29 +0000] "GET /logout HTTP/1.1" 302 46 "http://localhost:5000/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 OPR/58.0.3135.127" [hosting] Rewriting / to local function app error: Error: Can't set headers after they are sent. at validateHeader (_http_outgoing.js:491:11) at ServerResponse.setHeader (_http_outgoing.js:498:3) at ServerResponse.header (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/express/lib/response.js:767:10) at ServerResponse.send (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/express/lib/response.js:170:12) at done (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/express/lib/response.js:1004:10) at /home/ale/PycharmProjects/veople/webapp/functions/node_modules/consolidate/lib/consolidate.js:876:7 at /home/ale/PycharmProjects/veople/webapp/functions/node_modules/consolidate/lib/consolidate.js:161:5 at Promise._execute (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/bluebird/js/release/debuggability.js:313:9) at Promise._resolveFromExecutor (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/bluebird/js/release/promise.js:483:18) at new Promise (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/bluebird/js/release/promise.js:79:10) at promisify (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/consolidate/lib/consolidate.js:154:10) at Function.exports.handlebars.render (/home/ale/PycharmProjects/veople/webapp/functions/node_modules/consolidate/lib/consolidate.js:866:10) at /home/ale/PycharmProjects/veople/webapp/functions/node_modules/consolidate/lib/consolidate.js:181:27 at /home/ale/PycharmProjects/veople/webapp/functions/node_modules/consolidate/lib/consolidate.js:101:5 at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)

EDIT 2

index.js:

function createDatauser(firebaseUid, name, lastname){
    const docRef = db.collection('users').doc(firebaseUid);

    const setData = docRef.set({
      first: name,
      last: lastname
    });
}

...

app.get('/', (request, response) => {
    userService.checkUser( (firebaseUser) => {
        if (firebaseUser) {
            console.log(firebaseUser.email)
        }else {
            console.log('not logged in');
        }
        // response.set('Cache-Control', 'public, max-age=300, s-maxage=600');
        response.render('index', {firebaseUser});
    });



});



...

app.post("/register", (req, res) => {
 const nameRegister = req.body.name;
    const surnameRegister = req.body.surname;
    const emailRegister = req.body.emailRegister;
    const passwordRegister = req.body.passwordRegister;
    const confirmPasswordRegister = req.body.confirmPasswordRegister;
    console.log(emailRegister, passwordRegister);

 userService.registerUser(
   emailRegister,
   passwordRegister,

   (error, authData) => {
     if (error) {
       return res.status(401).send("Unauthorized");
     } else {
       res.redirect('/user');
       console.log(authData);
       createDatauser(authData.user.uid, nameRegister, surnameRegister);
       return authData
     }
   }
 );
});

...

app.get("/logout", (req, res) => {
 userService.logoutUser();
 res.redirect('/');

});

auth.js



function registerUser(email, password, callback) {
      console.log(email, password);
      firebase
        .auth()
        .createUserWithEmailAndPassword(email, password)
        .then((firebaseUser) => {
          // Success
          //console.log("Ok, lovely I'm registred", firebaseUser);
          callback(null, firebaseUser);
          return firebaseUser
        })
        .catch((error) => {
          // Error Handling
          // var errorCode = error.code;
          // var errorMessage = error.message;
          //console.log(errorCode); //auth/user-not-found
          //console.log(errorMessage); //There is no user record corresponding to this identifier. The user may have been deleted.

          callback(error);
        });
    }


...


function logoutUser(){
    firebase.auth().signOut()
        .then(() => {
            return null;
      // Sign-out successful.
    })
        .catch((error) => {
            return error;
      // An error happened.
    });
}

回答1:

Calling response.render(...) more then once will cause this error.

Solution is to remove the second render call so these 2 lines:

response.set('Cache-Control', 'public, max-age=300, s-maxage=600');
response.render('index');

So it should look like this:

app.get('/user', (request, response) => {
    userService.checkUser( (firebaseUser) => {
        if (firebaseUser) {
            response.render('user', {firebaseUser});
        }else {
            response.redirect('/');
        }
        // what is the bellow code even for??
        // above you either render user page
        // or redirect to /
        // response.set('Cache-Control', 'public, max-age=300, s-maxage=600');
        // response.render('index');
    });
});