3

I'm getting the following error on the browser when I run my react app on localhost which sends a payload to a Google Firebase function:

Access to fetch at 'https://< myproject >.cloudfunctions.net/< myfunction >' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

My Google Firebase function has the following code:

exports.<myfunction> = functions.https.onRequest(async (req, res) => {

  res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
  res.set('Access-Control-Allow-Headers', '*');

  console.log(req.body); 

  res.end()
});

The error I get on my firebase functions console log is the following:

SyntaxError: Unexpected token # in JSON at position 0 at JSON.parse () at createStrictSyntaxError (/worker/node_modules/body-parser/lib/types/json.js:157:10) at parse (/worker/node_modules/body-parser/lib/types/json.js:83:15) at /worker/node_modules/body-parser/lib/read.js:121:18 at invokeCallback (/worker/node_modules/raw-body/index.js:224:16) at done (/worker/node_modules/raw-body/index.js:213:7) at IncomingMessage.onEnd (/worker/node_modules/raw-body/index.js:273:7) at emitNone (events.js:111:20) at IncomingMessage.emit (events.js:208:7) at endReadableNT (_stream_readable.js:1064:12)

My Client side code which triggers the function is the following:

submit(name) {

    fetch('https://< myproject >.cloudfunctions.net/< my function >', {method: 'POST', headers: {"Content-Type": "application/json", 
      },
      body: 'mytoken'
    }).then(result => {console.log(result)}); 
  }

Also, everything was working fine just minutes and days earlier! It is as though this error started popping up out of nowhere.

pizza7
  • 441
  • 4
  • 17
  • u use `node` in server side? – Donald Wu Nov 10 '19 at 03:32
  • @DonaldWu I'm using Google Firebase Functions which uses Node – pizza7 Nov 10 '19 at 03:34
  • u use `express`? did u add `cors` lib in your node? https://github.com/expressjs/cors – Donald Wu Nov 10 '19 at 03:36
  • @DonaldWu to my knowledge I am *not* using express unless firebase functions automatically uses it in some way, but I don't believe it does – pizza7 Nov 10 '19 at 03:39
  • Any reason why you aren't using the standard cors module? https://stackoverflow.com/questions/42755131/enabling-cors-in-cloud-functions-for-firebase – Doug Stevenson Nov 10 '19 at 07:10
  • @DougStevenson I tried adding your solution ( npm installed CORS into Firebase functions and then added const cors = require('cors')({ origin: true, }); ) at the top of my firebase functions index.js file, and unfortunately nothing changed. – pizza7 Nov 10 '19 at 22:32
  • Did you actually **use** the cors module in the code for your function, beyond just importing it? It's not automatic. – Doug Stevenson Nov 10 '19 at 23:31
  • I got the same error and later realized that I forgot to deploy the functions using command - firebase deploy --only functions – Sandeep Amarnath Sep 15 '20 at 01:42

1 Answers1

3

Your fetch request is sending a Content-Type header of application/json but the body is 'mytoken' which is not valid JSON. Try sending something like {"token":"mytoken"} instead.

Edit: Additionally, since you are setting the Content-Type header you are likely triggering a CORS preflight OPTIONS request and may want to use the CORS middleware to handle it.

Edit 2: The source of the error was indeed the fact that a plain string was being sent instead of a JSON object (and a JSON object was necessary due to the fact that the content-type was set to application/json). There was, however, an additional bug afterwords in that the JSON payload needed to be stringify'd. Accordingly, the following code for "body" is what made everything run successfully:

body: JSON.stringify({token: 'mytoken'})
pizza7
  • 441
  • 4
  • 17
Michael Bleigh
  • 25,334
  • 2
  • 79
  • 85
  • Thanks for catching that! However, still doesn't solve the CORS issue – pizza7 Nov 10 '19 at 04:23
  • Your code isn't even being reached if there's a JSON parse error. What does your functions log print out now? – Michael Bleigh Nov 10 '19 at 04:26
  • I changed the body to body: {'token':'mytoken'}. Oddly, I'm getting two sets of responses on the server logs: Function execution started body text: {} Function execution took 111 ms, finished with status code: 200 Function execution started Function execution took 60 ms, finished with status code: 400 SyntaxError: Unexpected token o in JSON at position 1 at JSON.pars – pizza7 Nov 10 '19 at 04:32
  • 1
    Since you're setting `Content-Type` header, you may be triggering a CORS preflight. I'd recommend using the [CORS middleware](https://github.com/expressjs/cors) as someone suggested above to handle the `OPTIONS` request properly. I think that's likely the cause of your problem at this point. – Michael Bleigh Nov 11 '19 at 06:05
  • Using the JSON object now works, but I needed to use json.stringify() on the object. – pizza7 Nov 12 '19 at 02:44