Firebase任务将函数作为队列载荷传递

huangapple go评论64阅读模式
英文:

Firebase tasks pass function as queue payload

问题

我试图在Firebase中创建一个通用任务队列。

根据文档,我应该为每个需要的函数创建一个新队列,但我想创建一个通用队列,可以接受任何函数。

我尝试创建类似以下的内容:

export async function enqueue<T>(
  task: any, // 这将是在队列中执行的函数
  payload: T // 这是该函数的所有参数
): Promise<any> {
  if (isDev()) {
    // 在开发模式下,这将正常工作
    return await task(payload);
  }

  const FUNCTIONS_REGION = process.env.FUNCTIONS_REGION;
  const queue = functions.taskQueue(
    `locations/${FUNCTIONS_REGION}/functions/queue`
  );
  return await Promise.all([queue.enqueue({
    task,
    payload
  }, {
    dispatchDeadlineSeconds: 60 * 5 // 5分钟
  })]);
}

.......

exports.queue = functions
  .region(FUNCTIONS_REGION!)
  .tasks.taskQueue(queuesConfig)
  .onDispatch(async (data: QueueType) => {
    const {
      task,
      payload
    } = data;
    // 这里是我的问题,在GCP控制台中,任务显示为undefined
    console.log('task', task);
    // 但payload是正常的,一切都在那里
    console.log('payload', payload);
    await task(payload);
  })

如何将函数作为数据传递给我的队列?

英文:

I'm trying to create a generic task queue in firebase.

Following docs I'm supposed to create a new queue for each function I need but I want to create a generic queue that will accept any function.

I've tryed creating something like this

export async function enqueue&lt;T&gt;(
  task: any, // this will be the function that will be executed in the queue
  payload: T // this is all params for this function
): Promise&lt;any&gt; {
  if ( isDev() ) {
    // in dev mode this works fine
    return await task( payload )
  }

  const FUNCTIONS_REGION = process.env.FUNCTIONS_REGION
  const queue = functions.taskQueue(
    `locations/${ FUNCTIONS_REGION }/functions/queue`
  )
  return await Promise.all( [ queue.enqueue( {
    task,
    payload
  }, {
    dispatchDeadlineSeconds: 60 * 5 // 5 minutes
  } ) ] )
}

.......

exports.queue = functions
  .region( FUNCTIONS_REGION! )
  .tasks.taskQueue( queuesConfig )
  .onDispatch( async ( data: QueueType ) =&gt; {
    const {
      task,
      payload
    } = data
    // here&#39;s my problem, in GCP console, the task is showing as undefined
    console.log( &#39;task&#39;, task )
    // but the payload is ok, everything is there
    console.log( &#39;payload&#39;, payload )
    await task( payload )
  } )

How can I pass the function as data for my queue?

答案1

得分: 1

以下是翻译好的内容:

调用函数队列看起来是正确的:

import { getFunctions } from 'firebase-admin/functions';

function EnqueueIt() {
    const queuePath = `locations/{location}/functions/{functionName}`;
    const queue = getFunctions().taskQueue(queuePath);
    queue.enqueue({ task, payload });
}

从描述来看,task 似乎是一个 JavaScript 函数,如果是这种情况,它无法被序列化传输到队列中。这解释了为什么只有 payload 作为对象成功出现在队列中。

英文:

The call for a function queue looks correct:

import { getFunctions  } from &#39;firebase-admin/functions&#39;

function EnqueueIt() {
    const queuePath = `locations/{location}/functions/{functionName}`;
    const queue = getFunctions().taskQueue(queuePath);
    queue.enqueue({ task, payload });
}

From the description it looks like task is a JavaScript function, and in that case it is not serializable to be transferred to a queue. This explains why only payload as an Object successfully appears in the queue.

答案2

得分: 0

我已经找出了错误的原因... 当 Firebase 将任何任务排队时,它会向 Cloud Tasks API 发送 HTTP 请求,而这不支持将函数作为参数,因为所有数据都是 JSON,所以我的 'task' 变量始终未定义。在本地,这可以正常工作,因为JavaScript接受函数作为参数。

我最终使用了一个函数对象,'task' 是一个对象键。

英文:

Ok, I've figured out what was the error... when firebase enqueues any task it does a http request to cloud tasks API and this does not support functions as parameters because all data is a json so my 'task' variable was always undefined. Locally this works because JS accepts functions as parameters.

I ended using a functions object and 'taks' is an object key

huangapple
  • 本文由 发表于 2023年3月31日 20:04:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75898331.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定