'how to call firebase callable functions from localhost?
I get this error:
whenever this cloud function is called:
const makeAdmin = firebase.functions().httpsCallable("makeAdmin");
makeAdmin({
make: "admin"
})
.then(response => {
console.log(response);
})
.catch(err => console.error(err));
the function is:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();
const auth = admin.auth();
exports.makeAdmin = functions.https.onCall(async (data, context) => {
try {
const email = context.auth.token.email || null;
const user = await auth.getUserByEmail(email);
await auth.setCustomUserClaims(user.uid, {
admin: true
});
return {
message: "admin added successfully"
};
} catch (error) {
return error;
}
});
I tried using cors module but didn't work.
Solution 1:[1]
You need to enable cors
, to be able to do that request:
First install the package:
npm install cors
Then import it:
const cors = require('cors')({origin: true});
Solution 2:[2]
I know what needs to be done as I have faced the same
For localhost :: no need to install cors (better to uninstall) Modify your functions/index.js with reference to below
exports.yourFuncation = functions.https.onRequest((request, response) => {
response.set('Access-Control-Allow-Origin', "*")
/*Your code and response*/})
For Production : use the same code but Instead of localhost in cors use your production url
And should modify your firebase.json of firefunction as following
{
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
],
"headers": [{
"key": "Access-Control-Allow-Origin",
"value": "https://production.com/*"
}]
}}
Also you need to add cors values in your firebase.json under hosting
"rewrites": [{
"source": "**",
"destination": "/index.html",
"headers": [{
"key": "Access-Control-Allow-Origin",
"value": "https://us-central1-projectname.cloudfunctions.net*"
}]}]}
Modify things according , if u face problems leave a comment
Solution 3:[3]
As of January 15, 2020 new functions require authentication by default.
The solution was to manually add the Cloud Functions Invoker permission to the allUsers user in the Cloud Functions page in the Google Cloud Console.
Go to the Google Cloud Console: https://console.cloud.google.com/functions/
Click the checkbox next to the function on which you want to grant access.
Click Show Info Panel in the top right corner to show the Permissions tab.
Click Add member.
In the New members field, type allUsers.
Select the role Cloud Functions > Cloud Functions Invoker from the Select a role drop-down menu.
Click Save.
Solution 4:[4]
I had the exact same problem when I switched from using REST endpoints (created using functions.https.onRequest(...)
) and callable cloud functions (created using functions.https.onCall(...)
).
Typically, somewhere in a firebase client you'll pick between using the actual service layer and emulators running on localhost. If you're using cloud functions (vs. REST endpoints) then you need to explicitly tell the firebase client to use the functions emulator in much the same way as you have to for everything else, e.g.:
if (isTestMode) {
firebase.functions().useEmulator('localhost', 8501)
}
If you're using REST endpoints you run into the same issue, but you handle it by explicitly setting the url, e.g.
export const SERVICE_BASE_URL = isTestMode ?
'//localhost:8501/xxxxx-yyyyy/us-central1/' :
'//us-central1-xxxxx-yyyyy.cloudfunctions.net/'
Solution 5:[5]
Following @Peter Haddad and @Touha 's comment, I did this and it worked:
const cors = require("cors")({origin: true});
const {regionFunction} = require("./helpers/initFirebase");
const {getFacebookPageDataByOrganizationId} = require("./helpers/facebookIntegration");
exports.facebookIntegration = regionFunction.https.onRequest(async (req, res) => {
try {
const organizationId = req.query.organizationId;
const data = await getFacebookPageDataByOrganizationId({organizationId});
if (data && data.error) {
return cors(req, res, () => res.status(400).send(data));
}
return cors(req, res, () => res.status(200).send(data));
} catch (error) {
console.log("facebookIntegration func Error: ", error);
// return res.status(404).send(error);
return cors(req, res, () => res.status(400).send(error));
}
});
But, I don't understand why cors() has to be called this way. If anyone has a more complete answer please feel free to comment and I will update the answer to more comprehensive. Thanks.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Peter Haddad |
Solution 2 | Nandha Frost |
Solution 3 | Chan Wai Hsuen |
Solution 4 | podperson |
Solution 5 | Alexandre Desroches |