【问题标题】:Firebase Cloud Function Set Timeout 540s but ended at 60sFirebase Cloud Function Set Timeout 540s 但以 60s 结束
【发布时间】: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


    【解决方案1】:

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

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

    但您试图将其称为“可调用”函数,这是一种不同类型的函数:

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

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

    【讨论】:

    • 感谢@Doug 的指针,我创建了一个 onCall 方法,但它仍然会在 1 分钟内返回,而我故意“等待”了 3 分钟。设置和代码已在原始帖子中更新。
    • 抱歉,Firebase 开发团队有人吗?还是我可以将其报告为错误?我真的需要这个 T.T 的帮助......
    猜你喜欢
    • 2019-07-03
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 2020-10-26
    • 1970-01-01
    • 2019-08-13
    • 2021-05-02
    • 2023-03-13
    相关资源
    最近更新 更多