【问题标题】:How to use firebase emulators pubsub to test timed functions locally?如何使用 firebase 模拟器 pubsub 在本地测试定时功能?
【发布时间】:2020-07-29 21:38:47
【问题描述】:

我正在为一个项目使用 firebase,并且正在使用以下代码创建一个计划函数。我想每运行一分钟记录一条消息。

export const timedQuery = functions.pubsub.schedule('1 * * * *').onRun((context) => {
console.log("I am running")
return null;
})

我有在 http 函数下工作的代码的主要逻辑,并想在部署到生产之前看看它是否在本地工作。浏览firebase docs我已经下载了所有的firebase模拟器并使用“firebase emulators:start”让它们运行。从日志来看,我的 pubsub 模拟器似乎在 localhost:8085 成功启动,并且 pubsub 函数已初始化,但是即使等待 2-3 分钟后也没有打印出来。是否可以在本地测试预定功能?

由于我只在 firebase 上,所以我在没有使用谷歌云调度程序的情况下创建了这个。

【问题讨论】:

标签: typescript firebase google-cloud-functions localhost google-cloud-scheduler


【解决方案1】:

实际上有一个 Firebase PubSub 模拟器。要启用它,您需要安装最近的 CLI(肯定是在 8.2.0 中)

  • 重新运行 Firebase 初始化
  • 选择模拟器(空格键)
  • 选择 PubSub(以及您希望的其他)
  • 配置所需的开发端口
  • 让 CLI 安装模拟器

在本地创建一个测试脚本,将 PubSub 消息提交到队列中:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const { PubSub } = require('@google-cloud/pubsub');
const pubsub = new PubSub();

exports.pubsubWriter = functions.https.onRequest(async (req, res) => {
    console.log("Pubsub Emulator:", process.env.PUBSUB_EMULATOR_HOST);

    const msg = await pubsub.topic('test-topic').publishJSON({
        foo: 'bar',
        date: new Date()
    }, { attr1: 'value' });

    res.json({
        published: msg
    })
});

【讨论】:

【解决方案2】:

Firebase 本地模拟器目前不模拟实际的预定功能。 documentation 说:

Firebase CLI 包含一个 Cloud Functions 模拟器,它可以模拟 以下函数类型:

  • HTTPS 功能
  • 可调用函数
  • Cloud Firestore 函数

我建议向Firebase support 提交功能请求。

当您部署计划函数时,您实际上是在幕后使用 Google Cloud Scheduler。为您管理详细信息。如documentation中所述:

如果您想安排函数在指定时间运行,请使用 functions.pubsub.schedule().onRun() 这种便捷方法创建 Google Cloud Pub/Sub 主题并使用 Google Cloud Scheduler 触发该主题上的事件,确保您的函数按所需的时间表运行。

我建议将您的函数代码重构为一种方法,您可以通过使用您选择的测试框架直接调用它来进行测试。您也可以将其临时包装在 HTTP 函数中并以这种方式调用它。

【讨论】:

  • 好吧,我明白了。如果我想看到我的预定功能实时工作,我需要使用“firebase deploy”正确部署它吗?由于当前没有使用 firebase 模拟器进行本地测试的功能。
  • 是的,你必须部署它。
  • 如果有,pubsub 模拟器是干什么用的?
  • @AdiAzarya 用于通过主题创建的发布订阅
  • 这个答案只是部分正确。您可以使用 PubSub 模拟器,但没有调度程序。是的,最好将函数逻辑编写为单独的普通 JS/TS 函数或类方法,然后使用 Cloud Function 触发器绑定执行。
【解决方案3】:

解决方法

PubSub 模拟器尚不支持预定功能。

但是你可以使用firebase functions:shellsetInterval来模拟调度器。

注意:请确保您在本地运行 firebase 模拟器,否则 shell 可能会调用 Production 中的函数!!

firebase functions:shell

firebase > setInterval(() => yourScheduledFunc(), 60000)

不要退出,它会每 60 秒运行一次你的函数。

注意:在 shell 中运行的函数不会显示在模拟器的日志中。

【讨论】:

  • 非常感谢您的评论。
【解决方案4】:

由于某些原因,重新运行 firebase init 对我不起作用。

我最终手动修改了 firebase.json 文件,

引用related docs

通过运行 firebase init 模拟器或手动编辑 firebase.json 来更改模拟器端口。

// firebase.json
{
  "hosting": {
    // stuff...
  },
  "functions": {
    // stuff...
  },
  "emulators": {
    "functions": {
      "port": 5001
    },
    "hosting": {
      "port": 5000
    },
    "ui": {
      "enabled": true
    },
    "firestore": {
      "port": 8080
    },
    // * * * * * * * * *THIS? * * * * * * * * * * * * * * * * * * * * * * * 
    "pubsub": {
      "port": "8085"
    }
    // * * * * * * * * *THIS? * * * * * * * * * * * * * * * * * * * * * * * 
  },
  // more stuff...
}

【讨论】:

    猜你喜欢
    • 2020-10-26
    • 1970-01-01
    • 2018-11-25
    • 2018-05-11
    • 2021-10-13
    • 2020-10-30
    • 2021-04-22
    相关资源
    最近更新 更多