I'm having issues with Access-Control-Allow-Origin in combination with Firebase Cloud Functions.
I followed the examples to protect my https endpoints to make sure that only users with a valid token can access certain eindpoints.
I configured cors en imported the cors module. The strange thing is that I encounter completely random origin errors. Sometimes the request is valid and other times the request is invalid.
For reference and debugging, here are my cloud functions.
const cors = require('cors')({ origin: true });
const validateFirebaseIdToken = (async (req, res, next) => {
cors(req, res, async () => {
const authorization = req.headers.authorization;
let decodedToken;
if (!authorization) {
res.status(403).send('No token Provided');
return;
}
try {
decodedToken = await admin.auth().verifyIdToken(authorization);
req.user = decodedToken;
next();
} catch (error) {
res.status(403).send('Token is invalid Provided');
return;
}
});
});
const findUserByEmail = (async (req, res, next) => {
const emailAddress = req.body.emailAddress;
let userRecord;
if (!emailAddress) {
res.status(403).send('No email address provided');
return;
}
try {
userRecord = await admin.auth().getUserByEmail(emailAddress);
req.userRecord = userRecord.toJSON();
next();
} catch (error) {
if (error.code === 'auth/user-not-found') {
next();
}
res.status(403).send('Something went wrong', error);
return;
}
});
exports.createToken = functions.https.onRequest(async (req: any, res: any) => {
validateFirebaseIdToken(req, res, async () => {
const organizationUID = req.body.organizationUID;
let newToken;
if (!organizationUID) {
res.status(403).send('No organizationUID Provided');
return;
}
const additionalClaims = {
organizationUID
};
try {
newToken = await admin.auth().createCustomToken(req.user.uid, additionalClaims);
} catch (error) {
res.status(403).send('Error creating a new token');
console.log('error', error);
}
res.status(200).send({ token: newToken });
});
});
exports.returnUser = functions.https.onRequest(async (req: any, res: any) => {
validateFirebaseIdToken(req, res, async () => {
findUserByEmail(req, res, async () => {
if (req.userRecord) {
const user = {
uid: req.userRecord.uid,
newUser: false
};
res.status(200).json(user);
return;
}
let userRecord;
const randomPassword = Math.random().toString(36).slice(-12);
const newUser = {
email: req.body.emailAddress,
emailVerified: false,
password: randomPassword
};
try {
userRecord = await admin.auth().createUser(newUser);
req.userRecord = userRecord.toJSON();
const user = {
uid: req.userRecord.uid,
newUser: true
};
res.status(200).json(user);
return;
} catch (error) {
res.status(403).send('Can\'t generate new user');
}
});
});
});