将 Firebase 功能切换到 Gen-2

Che*_*niv 17 node.js firebase google-cloud-functions

我刚刚看到我们有第二代 Cloud Functions,看起来很棒: https: //cloud.google.com/functions/docs/2nd-gen/overview

但是我怎样才能将第一代功能切换为第二代呢?我发现我可以创建一个新函数作为第二代,如下所示

const functions = require('@google-cloud/functions-framework');

functions.http('helloHttp', (req, res) => {
 res.send(`Hello ${req.query.name || req.body.name || 'World'}!`);
});
Run Code Online (Sandbox Code Playgroud)

但旧功能呢?有没有办法或者我必须将它们一一删除并重新创建?

小智 11

Cloud Function Gen2 仅适用于产品 Cloud Functions,不适用于 Firebase 函数。
Firebase 函数使用该库firebase-functions,而 Cloud Functions 使用@google-cloud/functions-framework.
在 Google Cloud 控制台中,这两个函数将显示相同,但​​如果您尝试在 Cloud Function gen1 上部署 Cloud Function gen2,您将收到以下错误:

Failed to create function, function projects/[PROJECT_NUMBER]/locations/[LOCATION]/functions/[FUNCTION_NAME] already exists under 'Gen 1' environment. Please delete conflicting function first or deploy the function with a different name.

您需要从 Firebase 功能完全迁移到全新创建的 Cloud Functions gen2。

  • @NickJ,不确定何时切换,但看起来 Firebase 函数现在支持 Gen2(预览版):https://firebase.google.com/docs/functions/beta (7认同)
  • 您知道是否有计划改变这一现状?我们确实可以使用第二代的功能。 (2认同)

Mic*_*sky 7

自 2022 年 8 月 9 日第二代 Cloud Functions 全面可用以来,情况可能会发生变化,因此我将记录在 TypeScript 项目中对我有用的内容。

第一代

客户

“firebase”:“9.9.3”

import { httpsCallable } from "firebase/functions";
import { AddTwoNumbersInputParams, AddTwoNumbersInputResult } from "./util/shared/my-types";

// ...

const addTwoNumbersFuncCallable = httpsCallable<AddTwoNumbersInputParams, AddTwoNumbersInputResult>(
    firebaseFunctions,
    "addTwoNumbersFunc",
);

const result = await addTwoNumbersFuncCallable({
    firstNum: 3,
    secondNum: 5
});

console.log("Result", result.data);

Run Code Online (Sandbox Code Playgroud)

服务器

“firebase-functions”:“^3.21.0”

import * as functions from "firebase-functions";
import { AddTwoNumbersInputParams, AddTwoNumbersInputResult } from "./util/shared/my-types";

// ...

export const addTwoNumbersFunc = functions.https.runWith({ memory: "1GB" }).onCall((params: AddTwoNumbersInputParams, ctx): AddTwoNumbersInputResult => {
    
    if (!ctx.auth) {
        throw new functions.https.HttpsError("unauthenticated", "You must be logged in to call server-side functions");
    }


    return { result: params.firstNum + params.secondNum };
}

Run Code Online (Sandbox Code Playgroud)

共享

为了在客户端和服务器代码之间共享 TypeScript 接口 AddTwoNumbersInputParams 和 AddTwoNumbersInputResult,我创建了一个指向目录的符号链接,该目录util/shared在名为 my-types.ts 的文件中包含以下定义:

export interface AddTwoNumbersInputParams {
    firstNum: number
    secondNum: number
}

export interface AddTwoNumbersInputResult {
    result: number
}

Run Code Online (Sandbox Code Playgroud)

第二代

客户

“firebase”:“9.9.3”

import { httpsCallableFromURL } from "firebase/functions"; // see note1, note2, note3 below 

// ...

const addTwoNumbersFuncCallable = httpsCallableFromURL<AddTwoNumbersInputParams, AddTwoNumbersInputResult>(
    firebaseFunctions,
    "https://addtwonumbersfunc-fri67ycgta-uc.a.run.app",  // see note1, note2, note3 below 
);

const result = await addTwoNumbersFuncCallable({
    firstNum: 3,
    secondNum: 5
});

console.log("Result", result.data);

Run Code Online (Sandbox Code Playgroud)

注意1:可调用文档http-events文档都说该firebase deploy命令应该输出URL,但我没有看到它。我通过访问这里获得了它:

  1. Firebase 控制台
  2. 单击您的项目
  3. 单击“功能”(在左侧目录中,但如果没有看到它,请单击“所有产品”,然后单击“功能”)
  4. 在“触发器”列中复制函数的 URL;它应该是这样的形式https://<lowercase_func_name>-<random-hash>-<region>.a.run.app

注意2:起初我担心第二代函数会在我的持续集成管道中引入手动步骤,因为它们现在输出一个URL(或者它是这么说的)。由于多个 Firebase 项目代表了升级到生产的不同阶段(Google 的建议),我认为为第二代功能的每个部署复制和粘贴 URL 会遇到新的麻烦。幸运的是,它并没有我想象的那么糟糕,因为“部署后 URL 保持稳定”。因此,我只需部署一次即可获取 URL,将其插入到我的客户端代码中,然后此后的每次部署都保持不变。也就是说,对于我的每个 Firebase 项目来说,它仍然是不同的 URL。所以我必须做更多的工作来推广到生产。但也许他们会解决这个问题,因为他们说“在未来的版本中,第二代函数 URL 将更新为稳定且确定性的。”

注意3:我发现 URL 的东西太麻烦了,所以我在没有它的情况下尝试过,并在 Firebase Functions 模拟器上取得了成功,但在真正的 Firebase 项目上却没有成功。使用模拟器,我几乎能够继续使用httpsCallable()接受函数名称而不是httpsCallableFromURL()需要 URL 的函数。它可以在模拟器上运行,但不能在真正的 Firebase 项目中运行。

服务器

“firebase-functions”:“^3.21.0”

import * as functionsV2 from "firebase-functions/v2";
import {CallableRequest} from "firebase-functions/lib/common/providers/https";
import {HttpsOptions} from "firebase-functions/lib/v2/providers/https";

// ... 

const httpsOptions: HttpsOptions = {
    memory: "16GiB"  // see note4 below
};


// see note5 below
export const addtwonumbersfunc = functionsV2.https.onCall(httpsOptions, (request: CallableRequest<AddTwoNumbersInputParams>): AddTwoNumbersInputResult => {
    if (!request.auth) {
        throw new functionsV2.https.HttpsError("unauthenticated", "You must be logged in to call server-side functions");
    }

    return { result: request.data.firstNum + request.data.secondNum };
});


Run Code Online (Sandbox Code Playgroud)

注意4:runWith()设置内存(等)的语法似乎已更改为HttpsOptions您传递给onCall()接受HttpsOptions诸如memory. 第二代令人兴奋的事情之一是它提供比第一代更高的内存分配,因此我在这里演示了这一点,但从“1GB”增加到“16GiB”(另请注意从“GB”到“GiB”的变化)。

note5:“函数名称仅限于小写字母、数字和破折号。” 但希望很快就会出现“支持在函数名称中使用大写字母”。

共享

无需更改