Wei*_*ies 6 firebase google-cloud-functions angularfire2
我有我的云功能
\nimport * as functions from \'firebase-functions\';\nconst runtimeOpts = {\n timeoutSeconds: 540,\n memory: "1GB" as "1GB"\n\n}\n...\nexport const helloWorldAllowCORS = functions.runWith(runtimeOpts).https.onRequest(async (request, response) => {\n\n response.set(\'Access-Control-Allow-Origin\', \'*\');\n response.set(\'Access-Control-Allow-Credentials\', \'true\'); // vital\n\n response.set(\'Keep-Alive\', \'timeout=5, max=1000\');\n\n if (request.method === \'OPTIONS\') {\n // Send response to OPTIONS requests\n response.set(\'Access-Control-Allow-Methods\', \'GET\');\n response.set(\'Access-Control-Allow-Headers\', \'Content-Type\');\n response.set(\'Access-Control-Max-Age\', \'3600\');\n response.status(204).send(\'\');\n } else {\n let run = async (ms: any) => {\n await new Promise(resolve => setTimeout(resolve, ms));\n }\n await run(request.body.data.wait);\n\n response.send({\n data: {\n status: true\n , message: \'message v2 \'\n }\n })\n }\n});\nRun Code Online (Sandbox Code Playgroud)\n并从 Angular/Fire 插件触发
\n const callable = this.afFnc.httpsCallable("helloWorldAllowCORS");\n \n console.log(new Date());\n \n // wait for 3 min\n this.data = await callable({ wait: 180 * 1000 });\n\n this.data.subscribe(\n res => {\n console.log(new Date());\n console.log(res);\n },\n err => {\n console.log(new Date());\n console.error(err);\n }\nRun Code Online (Sandbox Code Playgroud)\n最终 chrome 控制台在 1 分钟内显示超时错误
\ncalling onTestCloudFunc()\n2020-06-26T03:42:08.387Z\n2020-06-26T03:43:18.401Z\nError: deadline-exceeded\n );\nRun Code Online (Sandbox Code Playgroud)\n我已经被这个问题困扰了好几天了。Firebase 官方文档没有详细介绍如何处理 CORS。一旦与 Angular/Fire 集成,httpCallable 函数就会失败。在我通过添加 header 解决了 CORS 问题之后。然而,新的 CORS 旁路逻辑再次打破了本应运行该进程 9 分钟的超时。
\n我还测试了,如果我增加超时,firebase官方https://firebase.google.com/docs/functions可以运行超过1分钟。但该代码只能通过手动复制并粘贴到 Chrome 浏览器中来运行。
\n我注意到,当 firebase + Angular/fire + 云功能 + 绕过 CORS 时,定义的超时 540 秒将失败。有人有完全集成的代码参考吗?
\n赞赏百万~~T_T...
\n更新: \n我创建了一个新的 onCall 函数\nAngular
\nconsole.log(\'Start Time: \', new Date());\n// wait for 3 min\n const callable = this.afFnc.httpsCallable("onCWaitASec");\n this.data = await callable({ wait: 3 * 60 * 1000 });\nthis.data.subscribe(\n res => {\n console.log(new Date());\n console.log(res);\n },\n err => {\n console.log(new Date());\n console.error(err);\n }\n);\nRun Code Online (Sandbox Code Playgroud)\nFirebase Cloud Func,onCall 方法:
\nexport const onCWaitASec = functions.runWith(runtimeOpts).https.onCall(async (data, context) => {\n \n let run = async (ms: any) => {\n await new Promise(resolve => setTimeout(resolve, ms));\n }\n await run(data.wait);\n\n return {\n status: \'success\',\n message: `this is onCWaitASec() return msg waited ${data.wait} `\n }\n})\nRun Code Online (Sandbox Code Playgroud)\nChrome 控制台
\nStart Time: Fri Jun 26 2020 14:42:56 GMT+0800 (Singapore Standard Time)\nlogin.component.ts:128 Fri Jun 26 2020 14:44:07 GMT+0800 (Singapore Standard Time)\nlogin.component.ts:129 Error: deadline-exceeded\n at new HttpsErrorImpl (index.cjs.js:58)\n at index.cjs.js:373\n at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)\n at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)\n at push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask (zone.js:503)\n at ZoneTask.invoke (zone.js:492)\n at timer (zone.js:3034)\nRun Code Online (Sandbox Code Playgroud)\nFirebase 控制台还显示超时为 540 秒。而chrome控制台的两个时间戳可以证明它在1分钟内超时\n
截至 7 月 1 日更新\n值得庆幸的是,我得到了 Firebase 支持团队 Mau 的帮助,他设法缩小了问题范围,是与 AngularFire 包有关,而不是与 Firebase SDK 本身有关。这里是最新的工作代码(使用官方 Firebase JS SDK 代替)
\n应用程序模块.ts
\nimport * as firebase from "firebase/app"; // official JS SDK\nimport { environment } from "../environments/environment";\nif (!firebase.apps.length) {\n firebase.initializeApp(environment.firebaseConfig);\n}\nRun Code Online (Sandbox Code Playgroud)\n应用程序组件.ts
\nimport * as firebase from "firebase/app";\nimport "firebase/functions";\n...\n async callCloudFnOfficial() {\n console.log("callCloudFnOfficial() Start Trigger At: ", new Date());\nvar callable = firebase.functions().httpsCallable("onCWaitASec", {timeout: 540000});\n callable({ wait: 500 * 1000 })\n .then(function(res) {\n console.log("success at ", new Date());\n console.log(res);\n })\n .catch(function(error) {\n console.log("Error at ", new Date());\n console.error(error);\n });\n }\nRun Code Online (Sandbox Code Playgroud)\nChrome 控制台日志
\nAngular is running in the development mode. Call enableProdMode() to enable the production mode.\ncallCloudFnOfficial() Start Trigger At:\n2020-07-01T01:04:21.130Z\nsuccess at\n2020-07-01T01:12:41.990Z\n{data: {\xe2\x80\xa6}}\ndata: Object\nmessage: "this is onCWaitASec() return msg waited 500000 "\nstatus: "success"\n__proto__: Object\n__proto__: Object\nRun Code Online (Sandbox Code Playgroud)\n因为它终于能够执行500秒并成功返回。与 Angular/Fire 相比,它总是在 1 分钟内返回
\nimport { AngularFireFunctions } from "@angular/fire/functions";\n...\n async callCloudFn() {\n console.log("Start Trigger At: ", new Date());\n const callable = this.fns.httpsCallable("onCWaitASec");\n // delay return for X seconds\n let cloudFncResp: Observable<any> = await callable({ wait: 500 * 1000 });\n cloudFncResp.subscribe(\n res => {\n console.log("success at ", new Date());\n console.log(res);\n },\n error => {\n console.log("Error at ", new Date());\n console.error(error);\n }\n );\n }\nRun Code Online (Sandbox Code Playgroud)\nChrome 控制台
\nStart Trigger At:\n2020-07-01T01:13:30.025Z\nError at\n2020-07-01T01:14:40.037Z\nError: deadline-exceeded\nRun Code Online (Sandbox Code Playgroud)\n还将报告 AngularFire 中的错误,因为它不允许我们在客户端应用程序中设置超时。之前曾在 firebase GitHub 中报道过。这是我提到的决议。
\n您已经使用 onRequest 声明了一个 HTTP 函数:
export const helloWorldAllowCORS = functions.runWith(runtimeOpts).https
.onRequest(async (request, response) => {
Run Code Online (Sandbox Code Playgroud)
但是您尝试将其称为“可调用”函数,这是一种不同类型的函数:
const callable = this.afFnc.httpsCallable("helloWorldAllowCORS");
Run Code Online (Sandbox Code Playgroud)
请务必通过彻底查看链接文档来注意HTTP 函数和可调用函数之间的区别。如果要使用 HTTP 函数,则不应使用用于可调用函数的客户端库来调用它。如果您想使用可调用函数,则应该使用 onCall,如文档中所示。