【问题标题】:Deleting Cloud Task from Cloud Functions从 Cloud Functions 中删除 Cloud Task
【发布时间】:2020-06-15 02:38:09
【问题描述】:

我正在尝试通过云功能删除 Google 云任务。这是我认为我需要基于谷歌文档的代码。

export const deleteHearingReminder = functions.firestore
  .document('Hearings/{HearingID}/Accepted/{AcceptedId}')
  .onUpdate(async change => {
    const dataBefore = change.before.data() as data;
    const dataAfter = change.before.data() as data;

    if (dataBefore === dataAfter) {
      console.log("Text didn't change");
      return null;
    }

    const taskID ={ name : dataAfter.taskId };

    const client = new CloudTasksClient();

    const [response] = await client.deleteTask(taskID);

    console.log(`delete task ${response.name}`);

    return Promise.resolve({ task: response.name });
  });

当这个函数被调用时,我得到一个错误

Error: 7 PERMISSION_DENIED: Permission denied on resource project 6cDNgaqLniz6kHGonePh.

其中 6cDN... 是我要删除的任务 ID,所以我的问题是我没有为谷歌任务提供足够的信息来删除我收到 PERMISSION_DENIED 错误的任务吗?此外,如果有更多信息,我应该提供相应的字段名称,因为从我在谷歌文档中看到的 deleteTask 只取“名称”。感谢您提出任何建议。

我非常感谢所有的帮助,所以现在我的代码看起来像这样。

const request = {
        name: `projects/${project}/locations/${location}/queues/${default_queue}/tasks/${dataAfter.taskId}`,
    };
    taskClient.deleteTask(request).catch(error => {
        console.error(`There was an error ${error}`);
    });

它工作得很好,非常感谢你,尽管这个 catch 方法仍然有错误

5 NOT_FOUND: Requested entity was not found

我已经对其进行了多次测试,结果一致,如果我担心这一点,它似乎确实按预期工作

【问题讨论】:

    标签: javascript google-cloud-functions google-cloud-tasks


    【解决方案1】:

    您需要为云功能服务帐户分配必要的权限才能删除任务。假设您使用默认的PROJECT_ID@appspot.gserviceaccount.com as 服务帐户运行云功能,只需将Cloud Tasks Task Deleter (Access to delete tasks) 角色授予服务帐户即可。

    Granting roles to service accounts

    【讨论】:

    • 不幸的是,这并没有解决问题,尽管我确实阅读了您附加的谷歌文档并查看这似乎是我正在寻找的解决方案,所以我不确定出了什么问题。我能否提供任何其他信息来帮助您更好地理解问题。
    • 我在 deleteTask 的末尾添加了一个 catch 并且看到我也得到了一个 Error: 3 INVALID_ARGUMENT: Invalid resource field value in the request. 我认为这与我将值传递给 deleteTask 的方式有关。这应该作为 http 请求传入吗?
    【解决方案2】:

    对于权限问题,您需要在 IAM 页面中为您的服务帐户使用角色 Cloud Tasks Delete

    但是,您正试图错误地删除任务。

    你可以看到here the official documentation关于任务删除。

    尝试关注example here,它显示了如何删除队列,而是删除您的任务

    async function deleteQueue(
      project = 'my-project-id', // Your GCP Project id
      queue = 'my-appengine-queue', // Name of the Queue to delete
      location = 'us-central1' // The GCP region in which to delete the queue
    ) {
      // Imports the Google Cloud Tasks library.
      const cloudTasks = require('@google-cloud/tasks');
    
      // Instantiates a client.
      const client = new cloudTasks.CloudTasksClient();
    
      // Get the fully qualified path to the queue
      const name = client.queuePath(project, location, queue);
    
      // Send delete queue request.
      await client.deleteQueue({name});
      console.log(`Deleted queue '${queue}'.`);
    }
    
    const args = process.argv.slice(2);
    deleteQueue(...args).catch(console.error);
    

    你传递的参数需要是任务的名称,格式如下:

    name=projects/[PROJECT_ID]/locations/[LOCATION]/queues/[QUEUE]/tasks/[TASK]
    

    Here你可以看到删除任务方法是如何工作的以及它期望收到什么。

      // Deletes a task.
      //
      // A task can be deleted if it is scheduled or dispatched. A task
      // cannot be deleted if it has completed successfully or permanently
      // failed.
      rpc DeleteTask(DeleteTaskRequest) returns (google.protobuf.Empty) {
        option (google.api.http) = {
          delete: "/v2beta2/{name=projects/*/locations/*/queues/*/tasks/*}"
        };
        option (google.api.method_signature) = "name";
      }
    

    【讨论】:

    • 谢谢,这确实解决了我的问题
    • 由于最初的问题现已解决,我建议您使用更新的代码和遇到的新错误打开一个新问题。我相信您很可能正在尝试删除队列中不再挂起的任务(如果任务已成功执行或永久失败,则无法删除。)因此您需要更改代码以尝试删除它,但如果它失败了然后不要崩溃,而是正常继续。
    相关资源