简体   繁体   English

Firebase 可调用 Function + CORS

[英]Firebase Callable Function + CORS

I'm trying to call a callable Cloud Function from my app, but I'm facing CORS issues.我正在尝试从我的应用程序调用可调用云 Function,但我面临 CORS 问题。 在此处输入图像描述

I can't enable Cors since I don't have access to the request and response on the onCall function. This is my function:我无法启用 Cors,因为我无法访问 onCall function 上的请求和响应。这是我的 function:

exports.UserInvitation = functions.https.onCall((data, context) => {
  const email = data.email


  return new Promise((resolve, reject) => {
    admin.auth().createUser({
      email: email,
      emailVerified: false,
      password: password
    }).then(resolve).catch((err) => {
      console.error(err.code)
      reject(new functions.https.HttpsError(err.code, err.message))
    })
  })
})

And this is how I call it:这就是我的称呼:

functions.httpsCallable('UserInvitation')({ email: this.input.value }).then((data) => {
      console.log('Sent invitation:', data)
})

Firebase-functions package.json: Firebase 函数 package.json:

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "serve": "firebase serve --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "dependencies": {
    "bluebird": "^3.5.1",
    "firebase-admin": "~5.12.0",
    "firebase-functions": "^1.0.1"
  },
  "private": true
}

WEB SDK Firebase version: 4.13.1 WEB SDK Firebase 版本:4.13.1

For anybody else who has arrived here searching firebase callable functions cors errors, here's my checklist:对于来到这里搜索 firebase 可调用函数 cors 错误的其他人,这是我的清单:

  1. Ensure the function is deployed.确保已部署该功能。
  2. Ensure the function name is correct.确保函数名称正确。 I was calling recalculatY when it should have been recalculateY .当它应该是recalculatY时,我正在调用recalculateY Got a cors error for some reason.由于某种原因出现 cors 错误。
  3. Ensure the function code itself is not throwing an error.确保函数代码本身没有抛出错误。 Use the emulator to help. 使用模拟器来帮助。 This didn't throw a cors error still helpful to know.这并没有引发 cors 错误仍然有助于了解。
  4. Ensure your regions match - I am using europe-west2 .确保您的地区匹配 - 我正在使用europe-west2 I had to both deploy the function with that region, and call it using the region.我必须在该区域中部署该功能,并使用该区域调用它。 For a while, I assumed the client would infer the correct region if the function name was correct.有一段时间,我认为如果函数名称正确,客户端会推断出正确的区域。 That was not the case.情况并非如此。

Deploying a callable function to a specific region:将可调用函数部署到特定区域:

// This is the file in which you define your callable function.
const functions = require('firebase-functions');
...
exports.yourFunc = functions.region('europe-west2').https.onCall(async (data, context) => {
    ...
})

Calling a function in a specific region from the client (in this case, a vuejs web app):从客户端调用特定区域中的函数(在本例中为 vuejs Web 应用程序):

// In my case, this is a vuex store file, but it is safe to assume this is plain old javascript
import firebase from 'firebase/app'
import 'firebase/functions'
...
firebase.app().functions('europe-west2').httpsCallable('yourFunc')

Note: firebase.app().function... vs firebase.app.function...注意: firebase.app().function... vs firebase.app.function...

For anyone looking at this post Jan 2020..对于任何在 2020 年 1 月看这篇文章的人..

Found this answer on Reddit ( https://www.reddit.com/r/reactjs/comments/fsw405/firebase_cloud_functions_cors_policy_error/ )在 Reddit 上找到了这个答案( https://www.reddit.com/r/reactjs/comments/fsw405/firebase_cloud_functions_cors_policy_error/

Turns out on 15th Jan 2020, Google changed the security settings where all new functions no longer have a Cloud Functions Invoker.结果是在 2020 年 1 月 15 日,Google 更改了安全设置,所有新功能都不再具有 Cloud Functions Invoker。 This means that all newly created functions will have their access forbidden, thus resulting in a CORS policy block.这意味着所有新创建的函数都将被禁止访问,从而导致 CORS 策略阻止。

Here is how you fix it, as it's not all that obvious:这是您修复它的方法,因为它并不那么明显:

https://cloud.google.com/functions/docs/securing/managing-access-iam#allowing_unauthenticated_function_invocation https://cloud.google.com/functions/docs/securing/managing-access-iam#allowing_unauthenticated_function_invocation

I had this problem with some of my Firebase functions but not others.我的某些 Firebase 函数遇到了这个问题,但其他函数没有。 I eventually fixed it by doing this:我最终通过这样做来修复它:

  1. Commenting the function out in index.js在 index.js 中注释掉函数
  2. Running firebase deploy运行 Firebase 部署
  3. Entering y at the prompt to delete the function在提示符下输入 y 以删除函数
  4. Waiting for 5 to 10 minutes等待 5 到 10 分钟
  5. Removing the comments around the function and running firebase deploy again删除函数周围的注释并再次运行 firebase deploy

Without any changes to the function itself, it now runs without any CORS issues.没有对函数本身进行任何更改,它现在可以在没有任何 CORS 问题的情况下运行。

My issue was not with CORS, but with my error handler.我的问题不在于 CORS,而在于我的错误处理程序。 Instead of rejecting the promise, I've used throw directly in the catch handler.我没有拒绝承诺,而是直接在 catch 处理程序中使用throw

catch((err) => {
  throw new functions.https.HttpsError('unknown', err.message, err)
})

Probably many will hit this issue with the emulator and cors messages.可能很多人会在模拟器和 cors 消息中遇到这个问题。

I havn't seen my case discussed in any discussion I've seen in Google, I do have seen many "can't reproduce", maybe my case will shade some light:我在谷歌看到的任何讨论中都没有看到我的案例讨论过,我确实看到了许多“无法复制”,也许我的案例会遮住一些光:

In my case the issue was that I wasn't running the hosting from the firebase emulator.就我而言,问题是我没有从 Firebase 模拟器运行托管。

When you run your react app via npm start - while the functions run via firebase emulators:start, you will see the Cors errors.当您通过 npm start 运行您的 React 应用程序时 - 当函数通过 firebase emulators:start 运行时,您将看到 Cors 错误。

So when testing cloud function calls, rather using npm start, you should do npm run build and then access the app from the emulator...所以在测试云函数调用时,而不是使用 npm start,你应该做 npm run build 然后从模拟器访问应用程序......

Search for something like: "hosting: Local server: http://localhost:5000 "搜索类似:“托管:本地服务器: http://localhost:5000

few notes -一些注意事项 -

  • Your functions should also work against the emulator via您的功能还应该通过以下方式针对模拟器工作

    const functions = firebaseApp.functions('europe-west3');// lets assume thats your region functions.useFunctionsEmulator('http://localhost:5000');

For those facing this error after enabling firebase on an existing GCloud project, there is some complexity which is not taken care of automatically as it would be if it were just a firebase app.对于在现有 GCloud 项目上启用 firebase 后遇到此错误的人来说,存在一些复杂性,如果它只是一个 firebase 应用程序,则不会自动处理。

I had this specific problem because I wanted my firebase function to be publicly accessible, but you have to specifically configure this if you're using google's Cloud Functions.我遇到了这个特定问题,因为我希望我的 firebase 函数可以公开访问,但是如果您使用的是谷歌的 Cloud Functions,则必须专门配置它。

Here are the steps to fix:以下是修复步骤:

  1. Go to the cloud function tab转到云功能选项卡
  2. Select your cloud function (check box)选择您的云功能(复选框)
  3. Click "Add members" under Permissions tab in the right side点击右侧权限选项卡下的“添加成员”
  4. Enter "allUsers"输入“所有用户”
  5. under "New memebers" Select Role as "Cloud Functions -> "Cloud Functions Invoker"在“新成员”下选择角色为“云函数->“云函数调用者”
  6. Save节省
  7. Test your cloud function by just pasting it in the browser只需将其粘贴到浏览器中即可测试您的云功能

Cheers干杯

If none of the above is helping: In my case the reason was that I havent correctly set up my regions.如果以上都没有帮助:就我而言,原因是我没有正确设置我的区域。 This can especially happen when using 3rd party libraries.使用 3rd 方库时尤其会发生这种情况。

If you are using multiple environments (Firebase Projects) to separate development and production (ie Project-dev, Project-prod), make sure you have switch to the desirable environment.如果您使用多个环境(Firebase 项目)来分离开发和生产(即 Project-dev、Project-prod),请确保您已切换到所需的环境。 In my case, running this worked:就我而言,运行它有效:

firebase use default

For me, I had to allow access to allUsers for the function.对我来说,我必须允许访问allUsers的所有用户。

  1. Go to Google Cloud Platform Console Cloud Functions. Go 到谷歌云平台控制台云功能。 You can click on the Detailed usage stats in the Functions tab on Firebase Console您可以单击 Firebase 控制台上功能选项卡中的Detailed usage stats 在此处输入图像描述

  2. Go to the Permissions tab Go 到权限选项卡

  3. Click Add点击添加

  4. Add appropriate permission添加适当的权限在此处输入图像描述

My "take" on the answers so far (plus my own personal experience) is that, for a Cloud function called by a javascript webapp, pretty much anything that goes wrong with the function will throw a CORS error.到目前为止,我对答案的“接受”(加上我自己的个人经验)是,对于由 javascript webapp 调用的云 function,function 出现的几乎所有问题都会引发 CORS 错误。 But one particular cause of error will be hosting the function in one region and calling it from another.但一个特定的错误原因是在一个区域托管 function 并从另一个区域调用它。 Here's some code you can use in a webapp to set this unambiguously so that you're not confused by the Firebase default (which, in any case, may not generally be appropriate).下面是一些代码,您可以在 Web 应用程序中使用它来明确地设置它,这样您就不会被默认值 Firebase 搞糊涂了(在任何情况下,默认值通常都不合适)。

import { initializeApp } from 'firebase/app';
import { getFunctions, httpsCallable } from 'firebase/functions';

const app = initializeApp(firebaseConfig);

const functions = getFunctions(app, '_my-region_');
const _my_function-name_= httpsCallable(functions, '_my-function-name_');

The function itself is then launched like this然后像这样启动 function 本身

_my-function-name_().then(response => console.log(response))

my-function-name must return a promise, eg: my-function-name必须返回 promise,例如:

exports.helloNewWorld = functions.region('europe-west2').https.onCall((data, context) => {
    const myPromise = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("foo");
        }, 300);
    });
    return myPromise
});

Google's background docs on all this are at https://firebase.google.com/docs/functions/callable#web-version-9 and https://firebase.google.com/docs/reference/js/functions#getfunctions Google 关于所有这些的背景文档位于https://firebase.google.com/docs/functions/callable#web-version-9https://firebase.google.com/docs/reference/js/functions#getfunctions

I previously had deployed my function as an HTTP function ( https.onRequest ), then switched to a callable function ( https.onCall ).我之前将我的函数部署为 HTTP 函数 ( https.onRequest ),然后切换到可调用函数 ( https.onCall )。 Firebase did not recognize this change. Firebase 无法识别此更改。

I solved the problem by removing the function and deploying without it, then putting the function back in and deploying again.我通过删除该功能并在没有它的情况下部署,然后将该功能放回并再次部署来解决该问题。

The status code passed to HttpsError cannot be test/code . 传递给HttpsError的状态代码不能是test/code It must be one of the standard codes listed here: https://firebase.google.com/docs/reference/functions/functions.https.HttpsError 它必须是此处列出的标准代码之一: https//firebase.google.com/docs/reference/functions/functions.https.HttpsError

  1. Errors should be as given in https://firebase.google.com/docs/reference/functions/functions.https.HttpsError错误应该在https://firebase.google.com/docs/reference/functions/functions.https.HttpsError 中给出
  2. I deployed callable function after changed function name and it's working.我在更改函数名称后部署了可调用函数并且它正在工作。

I got the same error when I tried to create a custom token for signing in a firebase user.当我尝试创建用于登录 firebase 用户的自定义令牌时,我遇到了同样的错误。 I have attached my code below.我在下面附上了我的代码。 However, I later discovered that the issue was due to attempting to create multiple tokens, by calling the function several times with the same parameters.但是,我后来发现问题是由于尝试使用相同的参数多次调用该函数来创建多个令牌。

export const getCustomToken = functions.https.onCall((params: any) => {
 return admin.auth().createCustomToken(params).then((token) => {
   return token;
  }).catch((error) => {
    console.log(error);
    return null;
  });
 });

SOLUTION解决方案
I solved the issue by first checking that the user is logged out before attempting to sign in. So I suggest that you first check if the user your trying to create already exists.我通过在尝试登录之前首先检查用户是否已注销来解决该问题。因此,我建议您首先检查您尝试创建的用户是否已经存在。 I know this is a bit late but I hope this helps some one else.我知道这有点晚了,但我希望这对其他人有所帮助。

this.fireAuth.currentUser.then((signedInAlready) => {
  if (signedInAlready) {
    return this.fireAuth.signOut().then(() => getCustomToken());
  } else {
    return getCustomToken();
  }
});

In your firebase functions you can check for an existing user as follows:在您的 firebase 函数中,您可以按如下方式检查现有用户:

admin.auth().getUserByEmail('your-email').then((userExists) => {
if (userExists) {
  // return user
} else {
  // create a new user
}});

I had the same issue.我遇到过同样的问题。 My solution was to open my Firebase project in https://console.cloud.google.com and navigated to cloud functions page.我的解决方案是在https://console.cloud.google.com 中打开我的 Firebase 项目并导航到云功能页面。

Look for your function name go to its permission page, and add new role "Cloud Functions Invoker" to "allUsers" member.查找您的函数名称,转到其权限页面,并将新角色“Cloud Functions Invoker”添加到“allUsers”成员。

Basically, I did everything mentioned in tones of pages and answers regarding CORS error for onCall cloud functions, from changing the region or manually adding the invoke permission to more obvious ones, nothing worked for me.基本上,我做了所有关于 onCall 云函数的 CORS 错误的页面和答案中提到的所有内容,从更改区域或手动添加调用权限到更明显的权限,对我来说没有任何作用。 Just turned the onCall onto OnRequest and it works.刚刚将 onCall 转到 OnRequest 并且它起作用了。

In my case, it was just an "undefined" value passed thru the httpsCallable... I have lost 3 hours because of the damn CORS error message... that has absolutely nothing to do with the CORS, I understand it's my fault for the undefined var.就我而言,它只是通过 httpsCallable 传递的“未定义”值...由于该死的 CORS 错误消息,我损失了 3 个小时...这与 CORS 完全无关,我知道这是我的错未定义的变量。 but I remember now I had the same issue 2 or 3 years ago, Please Google, fix this wrong error message !但我记得现在我在 2 或 3 年前遇到了同样的问题,请谷歌,修复这个错误的错误信息!

Permissions hiccup at the function level in my case too.在我的情况下,function 级别的权限也会出现问题。 All my callable functions were working fine, but one.我所有的可调用函数都运行良好,但只有一个。 Looking into their privileges in GCP, the working ones had a 'allUsers' principal with a 'Cloud Functions Invoker' role' set, but not the culprit.查看他们在 GCP 中的权限,工作人员有一个“allUsers”主体,并设置了一个“Cloud Functions Invoker”角色,但不是罪魁祸首。 Updated that and everything is now working.更新了,现在一切正常。

For anyone using gen2 firebase functions, callable functions need to be initialized differently.对于使用 gen2 firebase 函数的任何人,需要以不同方式初始化可调用函数。

Until Cloud Functions (2nd gen) supports cloudfunctions.net URLs, you will have to use a different initializer in your client code.在 Cloud Functions(第 2 代)支持 cloudfunctions.net URL 之前,您必须在客户端代码中使用不同的初始化程序。 Rather than providing a function name, provide a full URL to the client SDK. The URL for your function is printed at the end of a successful firebase deploy command:与其提供 function 名称,不如向客户端 SDK 提供完整的 URL。在成功的 firebase 部署命令结束时打印 function 的 URL:

https://firebase.google.com/docs/functions/beta/callable https://firebase.google.com/docs/functions/beta/callable

I just had the error when using the v2 cloud functions with the web sdk 9.12.在 web sdk 9.12 中使用 v2 云函数时,我刚刚遇到错误。

The solution for me was to not use the function name but the complete url of the v2 callable cloud function.我的解决方案是不使用 function 名称,而是使用 v2 可调用云 function 的完整名称url。

import { getFunctions, httpsCallableFromURL } from 'firebase/functions';

const functions = getFunctions();
const addMessage = httpsCallableFromURL(
  functions,
  // the URL of the function
  "https://addmessage-xyz1234-uc.a.run.app/addMessage"
);

addMessage({ text: messageText })
  .then((result) => {
    // Read result of the Cloud Function.
    const data = result.data;
    const sanitizedMessage = data.text;
  });

Snippets taken from the docs: https://firebase.google.com/docs/functions/beta/callable#web-version-9_2摘自文档的片段: https://firebase.google.com/docs/functions/beta/callable#web-version-9_2

What worked for me was to remove the region params in my cloud function and then redeploy.对我有用的是删除云函数中的区域参数,然后重新部署。

From functions.region("europe-west2").https.onCall(async (data) => {..functions.region("europe-west2").https.onCall(async (data) => {..

to functions.https.onCall(async (data) => {..functions.https.onCall(async (data) => {..

i try every thing - nothing work.我尝试了每一件事——没有任何效果。

  1. delete all function - not work...删除所有 function - 不起作用...
  2. set the cors header - you cant do it in callable function设置 cors header - 你不能在可调用的 function 中做到这一点
  3. add the "Cloud Functions Invoker" permission - it was allredy set..添加“Cloud Functions Invoker”权限 - 它已全部设置..
  4. add try catch -didnt help添加 try catch -didnt 帮助

till i found someone that tald to change the rewrite rules in angular.json only this work for me here is the complete guide from firestore docs - pay attantion - it works only from region us-central1直到我发现有人说要更改 angular.json 中的重写规则

how to solve CORS on firestore onCall function with context 如何通过上下文解决 Firestore onCall function 上的 CORS

anoter docs on CORs problem in callable functions 关于可调用函数中 CORs 问题的另一个文档

my lib versions我的库版本

angualr 13

"@angular/fire": "^7.2.0",

"firebase": "^9.4.0",

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Firebase 可调用云 Function CORS 错误使用 Z035489FF8D092741943E4A83241F5 - Firebase Callable Cloud Function CORS Error using Firebase Emulator and Vite 从 Angular 调用 Firebase 可调用函数时出现 CORS 错误? - CORS error when calling Firebase Callable Functions from Angular? Firebase 可调用函数模拟器配置不起作用 - Firebase Callable Function Emulator configuration not working Firebase 云 function cors 即使添加 cors 中间件也会出错 - Firebase cloud function cors error even when adding cors middleware 从 Firebase 可调用 function(云功能)返回 stream 的正确方法? - Proper way to return stream from Firebase callable function (Cloud function)? 启用 App Check 的单元测试可调用 firebase function - Unit testing callable firebase function with App Check enabled Firebase Cloud Functions - 从 https 中的上下文获取来源可调用 function - Firebase Cloud Functions - get origin from context in https callable function 从 PWA 服务工作者调用 Firebase Callable Function 以响应对推送通知的点击 - Calling a Firebase Callable Function from a PWA service worker in response to a click on a push notification 如何从 TypeScript 中的可调用 Firebase Cloud Function 向我的 Unity 应用程序发送自定义 object? - How can I send custom object from my callable Firebase Cloud Function in TypeScript to my Unity app? 当您修改许多其他函数使用的代码时,Firebase 如何更新一个可调用的 function - How does Firebase update one callable function when you modify a code used by many other functions
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM