How to solve request.body is undefined in Firebase Cloud Functions

A few days ago, I was trying to implement a payment process via Stripe and Firebase Cloud Functions.

The idea was to use the Stripe library to generate a user's payment token and send this token to the Firebase Cloud Function using the fetch method.

Finally, use that token to charge the user.

Initial approach (wrong)

So, this was the user's function:

javascript
let response = await fetch(url, {
  "method": "POST",
  "headers": {
    "Content-Type": "application/json"
  },
  "body": JSON.stringify({"stripeToken": token.id})
});

And this was the initial Firebase Cloud Function:

javascript
const functions = require('firebase-functions');
const cors = require('cors')({origin: true});
const stripe = require('stripe')(functions.config().stripe.token);
// Remember to type command before deploying → firebase functions:config:set stripe.token="PRIVATE_KEY"

// 🔴 This function doesn't work. 
// request.body is blocked by the CORS policy...

exports.chargeStripe = functions.https.onRequest( async (request, response) => {

    // Getting token
    let token = request.body.stripeToken;
    
    // Creating charge
    let charge = await stripe.charges.create({
        amount: 99,
        currency: 'eur',
        description: 'Payment',
        source: token
    });
    
    // Sending response
    charge 
    ? response.status(200).send('Success!')
    : response.status(500).send('Error!');
    
});

The problem was that I was getting blocked by the browser's CORS policy and request.body was undefined. So I could not charge the user...

Final approach (right)

Thanks to Doug Stevenson, I understood that not only I needed to import the cors package, but I needed to use its functions as well (😅).

So, the final solution was:

javascript
const functions = require('firebase-functions');
const cors = require('cors')({origin: true});
const stripe = require('stripe')(functions.config().stripe.token);
// Remember to type command before deploying → firebase functions:config:set stripe.token="PRIVATE_KEY"

// ✅ This function works as expected!
// It's not blocked by the CORS policy

exports.chargeStripe = functions.https.onRequest( (request, response) => {

    // Enable CORS using the `cors` express middleware.
    return cors(request, response, async () => {

        // Reading token
        let token = request.body.stripeToken;

        // Charging user
        let charge = await stripe.charges.create({
            amount: 99,
            currency: 'eur',
            description: 'Payment',
            source: token
        });

        // Sending response 
        charge 
        ? response.status(200).send('Success!')
        : response.status(500).send('Error!');
    });

}); 

Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.