我有我的云功能
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 func就失败了。在我通过添加标题解决了CORS问题之后。然后,新的CORS旁路逻辑再次打破了超时,该超时应该运行该进程9分钟。
我也测试过,firebase官方https://firebase.google.com/docs/functions可以运行超过1分钟,如果我增加超时。但是代码只能通过手动复制和粘贴到chrome浏览器中来运行。
我注意到,当firebase + angular/fire + cloud function + bypass CORS时,定义的Timeout 540 s将失败。有人有完整的代码参考吗?
以百万计的升值~~ T_T...
**更新:**我创建了一个新的onCall函数Angular
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函数,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 s。而chrome控制台的两个时间戳可以证明它在1分钟内超时x1c 0d1x
更新至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秒并成功返回。与angular/fire相比,总是在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中的bug,因为它不允许我们在客户端应用程序中设置超时。是reported in firebase GitHub before这是我提到的决议。
1条答案
按热度按时间agxfikkp1#
你已经用onRequest声明了一个HTTP函数:
但是你试图把它作为一个“可调用”函数来调用,这是一个不同类型的函数:
如果要注意HTTP function和callable function之间的区别,请仔细阅读链接文档。如果要使用HTTP函数,则不应使用用于可调用函数的客户端库来调用它。如果你想使用一个可调用的函数,你应该使用onCall,如文档所示。