英文:
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<T>(
  task: any, // this will be the function that will be executed in the queue
  payload: T // this is all params for this function
): Promise<any> {
  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 ) => {
    const {
      task,
      payload
    } = data
    // here's my problem, in GCP console, the task is showing as undefined
    console.log( 'task', task )
    // but the payload is ok, everything is there
    console.log( 'payload', 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 'firebase-admin/functions'
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论