我尝试从应用程序调用函数,但它不起作用,并且我从控制台收到以下错误:
index.esm.js:402选项https://us-central1-undefined.cloudfunctions.net/addMessage 404() 无法加载https://us-central1-undefined.cloudfunctions.net/addMessage:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问来源“https://MYWEBADDRESS”。响应的 HTTP 状态代码为 404。如果不透明响应满足您的需求,请将请求的模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。
firebase.json:
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "public",
"rewrites": [
{
"source": "**",
"function": "addMessage"
}
]
},
"functions": {
"predeploy": [
"npm --prefix $RESOURCE_DIR run lint"
],
"source": "functions"
}
}
index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.addMessage = functions.https.onCall((data, context) => {
// Message text passed from the client.
const text = data.text;
// Checking attribute.
if (!(typeof text === 'string') || text.length === 0) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('invalid-argument', 'The function must be called with ' +
'one arguments "text" containing the message text to add.');
}
// Checking that the user is authenticated.
if (!context.auth) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
'while authenticated.');
}
// Saving the new message to the Realtime Database.
return admin.database().ref('/messages').push({
text: text
}).then(() => {
console.log('New Message written');
// Returning the sanitized message to the client.
return { text: sanitizedMessage };
}).catch((error) => {
// Re-throwing the error as an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('unknown', error.message, error);
});
});
我的脚本在index.html
var addMessage = firebase.functions().httpsCallable('addMessage');
addMessage({text: "messageText"}).then(function(result) {
var message = result.data.text;
console.log(message);
});
如何初始化 Firebase:
<script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-functions.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "**",
authDomain: "***",
databaseURL: "***",
storageBucket: "***",
};
firebase.initializeApp(config);
var functions = firebase.functions();
</script>
我遇到了同样的问题,发现你的问题没有答案,但最终设法解决了。
正如 @Doug Stevenson 在评论中提到的,问题是您看到的 Cloud Functions URL 的 url 子域的最后一部分是
undefined
,而不是您的项目 ID。
它未定义的原因是您的项目 ID 不是初始 Firebase 配置对象的一部分。和我一样,您可能从 Firebase 中复制并粘贴了 JS SDK 的起始代码片段,但您是在他们开始将项目 ID 包含在其中之前完成的。由于某种原因,即使现在需要项目 ID 来构建云函数 URL,但如果您不包含它,SDK 也不会发出错误/警告。
您需要做的就是将以下字段添加到您的
config
对象中:
projectId: <YOUR_PROJECT_ID_HERE>
然后您应该会看到请求不再是 404。
对于任何其他偶然发现这个问题但遇到相同错误的人,即使
projectId
已经设置:如果您碰巧使用 Express.js 作为您的函数,请查看此 Github 问题 和此 StackOverflow 评论.
总结一下:确保在使用 Express 设置函数时包含函数的完整 URI。例如,如果您的函数在
https://us-central1.your-project-id.cloudfunctions.net/api/addMessage
下运行,请确保也包含 api/
部分。所以,在这个例子中,这将是:
app.post('/api/addMessage', addMessage);