【发布时间】:2020-06-26 03:54:59
【问题描述】:
我有我的云功能
import * as functions from 'firebase-functions';
const runtimeOpts = {
timeoutSeconds: 540,
memory: "1GB" as "1GB"
}
...
export const helloWorldAllowCORS = functions.runWith(runtimeOpts).https.onRequest(async (request, response) => {
response.set('Access-Control-Allow-Origin', '*');
response.set('Access-Control-Allow-Credentials', 'true'); // vital
response.set('Keep-Alive', 'timeout=5, max=1000');
if (request.method === 'OPTIONS') {
// Send response to OPTIONS requests
response.set('Access-Control-Allow-Methods', 'GET');
response.set('Access-Control-Allow-Headers', 'Content-Type');
response.set('Access-Control-Max-Age', '3600');
response.status(204).send('');
} else {
let run = async (ms: any) => {
await new Promise(resolve => setTimeout(resolve, ms));
}
await run(request.body.data.wait);
response.send({
data: {
status: true
, message: 'message v2 '
}
})
}
});
并从 angular/fire 插件触发
const callable = this.afFnc.httpsCallable("helloWorldAllowCORS");
console.log(new Date());
// wait for 3 min
this.data = await callable({ wait: 180 * 1000 });
this.data.subscribe(
res => {
console.log(new Date());
console.log(res);
},
err => {
console.log(new Date());
console.error(err);
}
chrome 控制台在 1 分钟内显示超时错误
calling onTestCloudFunc()
2020-06-26T03:42:08.387Z
2020-06-26T03:43:18.401Z
Error: deadline-exceeded
);
这几天我一直在纠结这个问题。官方的 firebase 文档并没有说明如何处理 CORS。一旦与 angular/fire 集成,httpCallable 函数就会失败。在我通过添加标题解决了 CORS 问题之后。话又说回来,新的 CORS 绕过逻辑打破了应该运行该进程 9 分钟的超时。
我也测试过,如果我增加超时,firebase 官方https://firebase.google.com/docs/functions 可以运行超过 1 分钟。但是代码只能通过手动复制粘贴到chrome浏览器中运行。
我注意到,当 firebase + angular/fire + cloud function + bypass CORS 时,定义的 Timeout 540s 将失败。谁有完全集成的代码参考?
百万升值~~T_T...
更新: 我创建了一个新的 onCall 函数 角度
console.log('Start Time: ', new Date());
// wait for 3 min
const callable = this.afFnc.httpsCallable("onCWaitASec");
this.data = await callable({ wait: 3 * 60 * 1000 });
this.data.subscribe(
res => {
console.log(new Date());
console.log(res);
},
err => {
console.log(new Date());
console.error(err);
}
);
Firebase Cloud Func,onCall 方法:
export const onCWaitASec = functions.runWith(runtimeOpts).https.onCall(async (data, context) => {
let run = async (ms: any) => {
await new Promise(resolve => setTimeout(resolve, ms));
}
await run(data.wait);
return {
status: 'success',
message: `this is onCWaitASec() return msg waited ${data.wait} `
}
})
Chrome 控制台
Start Time: Fri Jun 26 2020 14:42:56 GMT+0800 (Singapore Standard Time)
login.component.ts:128 Fri Jun 26 2020 14:44:07 GMT+0800 (Singapore Standard Time)
login.component.ts:129 Error: deadline-exceeded
at new HttpsErrorImpl (index.cjs.js:58)
at index.cjs.js:373
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
at push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask (zone.js:503)
at ZoneTask.invoke (zone.js:492)
at timer (zone.js:3034)
Firebase 控制台还将超时显示为 540 秒。而chrome控制台的两个时间戳可以证明它在1分钟内超时
自 7 月 1 日起更新 谢天谢地,我从 Firebase 支持团队的 Mau 那里得到了帮助,他设法缩小了问题的范围是 AngularFire 包而不是 Firebase SDK 本身。这里是最新的工作代码(使用官方 Firebase JS SDK)
app.module.ts
import * as firebase from "firebase/app"; // official JS SDK
import { environment } from "../environments/environment";
if (!firebase.apps.length) {
firebase.initializeApp(environment.firebaseConfig);
}
app.component.ts
import * as firebase from "firebase/app";
import "firebase/functions";
...
async callCloudFnOfficial() {
console.log("callCloudFnOfficial() Start Trigger At: ", new Date());
var callable = firebase.functions().httpsCallable("onCWaitASec", {timeout: 540000});
callable({ wait: 500 * 1000 })
.then(function(res) {
console.log("success at ", new Date());
console.log(res);
})
.catch(function(error) {
console.log("Error at ", new Date());
console.error(error);
});
}
Chrome 控制台日志
Angular is running in the development mode. Call enableProdMode() to enable the production mode.
callCloudFnOfficial() Start Trigger At:
2020-07-01T01:04:21.130Z
success at
2020-07-01T01:12:41.990Z
{data: {…}}
data: Object
message: "this is onCWaitASec() return msg waited 500000 "
status: "success"
__proto__: Object
__proto__: Object
因为它终于能够执行 500 秒并成功返回。与角度/火力相比,总是在 1 分钟内返回
import { AngularFireFunctions } from "@angular/fire/functions";
...
async callCloudFn() {
console.log("Start Trigger At: ", new Date());
const callable = this.fns.httpsCallable("onCWaitASec");
// delay return for X seconds
let cloudFncResp: Observable<any> = await callable({ wait: 500 * 1000 });
cloudFncResp.subscribe(
res => {
console.log("success at ", new Date());
console.log(res);
},
error => {
console.log("Error at ", new Date());
console.error(error);
}
);
}
Chrome 控制台
Start Trigger At:
2020-07-01T01:13:30.025Z
Error at
2020-07-01T01:14:40.037Z
Error: deadline-exceeded
还会报告 AngularFire 中的错误,因为它不允许我们在客户端应用程序中设置超时。这是reported in firebase GitHub before。这里是我提到的the resolution。
【问题讨论】:
标签: firebase google-cloud-functions angularfire2