Firebase云函数集超时540s,但在60s结束

toiithl6  于 2023-05-29  发布在  其他
关注(0)|答案(1)|浏览(101)

我有我的云功能

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这是我提到的决议。

agxfikkp

agxfikkp1#

你已经用onRequest声明了一个HTTP函数:

export const helloWorldAllowCORS = functions.runWith(runtimeOpts).https
    .onRequest(async (request, response) => {

但是你试图把它作为一个“可调用”函数来调用,这是一个不同类型的函数:

const callable = this.afFnc.httpsCallable("helloWorldAllowCORS");

如果要注意HTTP functioncallable function之间的区别,请仔细阅读链接文档。如果要使用HTTP函数,则不应使用用于可调用函数的客户端库来调用它。如果你想使用一个可调用的函数,你应该使用onCall,如文档所示。

相关问题