简体   繁体   English

如何在本地测试`functions.https.onCall` firebase 云功能?

[英]How to test `functions.https.onCall` firebase cloud functions locally?

I can't seem to find the solution for this in the Firebase Documentation .我似乎无法在Firebase 文档中找到解决方案。

I want to test my functions.https.onCall functions locally.我想在本地测试我的functions.https.onCall函数。 Is it possible using the shell or somehow connect my client (firebase SDK enabled) to the local server?是否可以使用 shell 或以某种方式将我的客户端(启用 Firebase SDK)连接到本地服务器?

I want to avoid having to deploy every time just to test a change to my onCall functions.我想避免每次只为了测试对onCall函数的更改而进行部署。


My code我的代码

Function :功能 :

exports.myFunction = functions.https.onCall((data, context) => {
  // Do something
});

Client:客户:

const message = { message: 'Hello.' };

firebase.functions().httpsCallable('myFunction')(message)
  .then(result => {
    // Do something //
  })
  .catch(error => {
    // Error handler //
  });

对于本地,您必须调用(在 firebase.initializeApp 之后)

firebase.functions().useFunctionsEmulator('http://localhost:5000') 

Callables are just HTTPS functions with a specific format. Callables 只是具有特定格式的 HTTPS 函数。 You can test just like a HTTPS function , except you have to write code to deliver it the protocol as defined in the documentation .您可以像测试 HTTPS 功能一样进行测试,不同之处在于您必须编写代码以向其提供 文档中定义的协议。

Although the official Firebase Cloud Function docs have not yet been updated, you can now use firebase-functions-test with onCall functions.尽管官方 Firebase Cloud Function 文档尚未更新,但您现在可以将onCall -functions-testonCall函数一起使用。

You can see an example in their repository .您可以在他们的存储库中看到一个示例

I have managed to test my TypeScript functions using jest, here is a brief example.我已经设法使用 jest 测试了我的 TypeScript 函数,这是一个简短的例子。 There are some peculiarities here, like import order, so make sure to read the docs :-)这里有一些特殊性,比如导入顺序,所以一定要阅读文档:-)

/* functions/src/test/index.test.js */
/* dependencies: Jest and jest-ts */

const admin = require("firebase-admin");
jest.mock("firebase-admin");
admin.initializeApp = jest.fn(); // stub the init (see docs)
const fft = require("firebase-functions-test")();

import * as funcs from "../index";

// myFunc is an https.onCall function
describe("test myFunc", () => {
  // helper function so I can easily test different context/auth scenarios
  const getContext = (uid = "test-uid", email_verified = true) => ({
    auth: {
      uid,
      token: {
        firebase: {
          email_verified
        }
      }
    }
  });
  const wrapped = fft.wrap(funcs.myFunc);

  test("returns data on success", async () => {
    const result = await wrapped(null, getContext());
    expect(result).toBeTruthy();
  });

  test("throws when no Auth context", async () => {
    await expect(wrapped(null, { auth: null })).rejects.toThrow(
      "No authentication context."
    );
  });
});

There is a simple trick, how you can simplify onCall -function testing.有一个简单的技巧,如何简化onCall函数测试。 Just declare the onCall function callback as a local function and test that instead:只需将 onCall 函数回调声明为本地函数并进行测试:

const _myFunction = (data, context) => { // <= call this on your unit tests
  // Do something
}

exports.myFunction = functions.https.onCall(_myFunction);

Now you can variate all cases with a normal function with the input you define on your function call.现在,您可以使用在函数调用中定义的输入,使用普通函数来改变所有情况。

you should first check for dev environment and then point your functions to local emulator.您应该首先检查开发环境,然后将您的功能指向本地模拟器。
For JS:对于JS:

//after firebase init
if (window.location.host.includes("localhost") ||
    window.location.host.includes("127.0.0.1")
) {
    firebase
      .app()
      .functions()  //add location here also if you're mentioning location while invoking function()
      .useFunctionsEmulator("http://localhost:5001");
  }

or if you don't create instance of firebase then或者,如果您不创建 firebase 实例,则

//after firebase init
if (window.location.host.includes("localhost") || 
   window.location.host.includes("127.0.0.1")
) {
    firebase
      .functions()
      .useFunctionsEmulator("http://localhost:5001");
  }

or when serving pages from backend (node.js):或从后端(node.js)提供页面时:

//after firebase init
if (process.env.NODE_ENV === 'development') {
  firebase.functions().useFunctionsEmulator('http://localhost:5001');
}

if you are using angularfire, add this to you app.module如果您使用的是 angularfire,请将其添加到您的 app.module

{
  provide: FirestoreSettingsToken,
  useValue: environment.production
    ? undefined
    : {
        host: "localhost:5002",
        ssl: false
      }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM