You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase Cloud Functions部署失败:服务代理IAM角色权限问题

Firebase Cloud Functions部署问题:onObjectFinalized函数部署失败

问题概述

项目包含http、onSchedule、onObjectFinalized三个函数,其中http与onSchedule可成功部署,但onObjectFinalized函数部署失败。本人拥有Cloud Functions Admin和Editor角色,已查阅官方文档与技术论坛未找到有效方案。

完整错误信息

$ npm run deploy:prod

> cloud-functions@1.0.0 deploy:prod      
> npm run changeToProd && firebase deploy


> cloud-functions@1.0.0 changeToProd
> firebase use prod

Now using alias prod (zipshot-prod)

=== Deploying to 'zipshot-prod'...

i  deploying functions, hosting   
i  functions: preparing codebase default for deployment
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i  functions: ensuring required API cloudbuild.googleapis.com is enabled...
i  artifactregistry: ensuring required API artifactregistry.googleapis.com is enabled...
+  functions: required API cloudfunctions.googleapis.com is enabled
+  artifactregistry: required API artifactregistry.googleapis.com is enabled
+  functions: required API cloudbuild.googleapis.com is enabled
i  functions: Loading and analyzing source code for codebase default to determine what to deploy
Serving at port 8581

{"severity":"WARNING","message":"params.PROJECT_ID.value() invoked during function deployment, instead of during runtime."}

{"severity":"WARNING","message":"This is usually a mistake. In configs, use Params directly without calling .value()."}
{"severity":"WARNING","message":"example: { memory: memoryParam } not { memory: memoryParam.value() }"}

i  functions: preparing functions directory for uploading...
i  functions: packaged F:\\project\\chrome_ext\\zipshot\\cloud-functions\\functions (109.47 KB) for uploading
i  functions: ensuring required API cloudscheduler.googleapis.com is enabled...
+  functions: required API cloudscheduler.googleapis.com is enabled
i  functions: ensuring required API run.googleapis.com is enabled...
i  functions: ensuring required API eventarc.googleapis.com is enabled...
i  functions: ensuring required API pubsub.googleapis.com is enabled...
i  functions: ensuring required API storage.googleapis.com is enabled...
+  functions: required API run.googleapis.com is enabled
+  functions: required API storage.googleapis.com is enabled
+  functions: required API pubsub.googleapis.com is enabled
+  functions: required API eventarc.googleapis.com is enabled
i  functions: generating the service identity for pubsub.googleapis.com...
i  functions: generating the service identity for eventarc.googleapis.com...
i  functions: Failed to verify the project has the correct IAM bindings for a successful deployment.
i  functions: You can either re-run `firebase deploy` as a project owner or manually run the 
following set of `gcloud` commands:
i  functions: `gcloud projects add-iam-policy-binding zipshot-prod --member=serviceAccount:service-1090842465135@gs-project-accounts.iam.gserviceaccount.com --role=roles/pubsub.publisher`
i  functions: `gcloud projects add-iam-policy-binding zipshot-prod --member=serviceAccount:service-1090842465135@gcp-sa-pubsub.iam.gserviceaccount.com --role=roles/iam.serviceAccountTokenCreator`
i  functions: `gcloud projects add-iam-policy-binding zipshot-prod --member=serviceAccount:1090842465135-compute@developer.gserviceaccount.com --role=roles/run.invoker`
i  functions: `gcloud projects add-iam-policy-binding zipshot-prod --member=serviceAccount:1090842465135-compute@developer.gserviceaccount.com --role=roles/eventarc.eventReceiver`       

Error: We failed to modify the IAM policy for the project. The functions deployment requires 
specific roles to be granted to service agents, otherwise the deployment will fail.

index.js核心代码片段

const {onRequest} = require("firebase-functions/v2/https");
const {onObjectFinalized} = require("firebase-functions/v2/storage");
const {getStorage} = require("firebase-admin/storage");
const {onSchedule} = require("firebase-functions/v2/scheduler");
const {initializeApp} = require("firebase-admin/app");
const logger = require("firebase-functions/logger");
const path = require("path")
const sharp = require("sharp")

initializeApp();

const app = require("./app.js");
const {projectID} = require("firebase-functions/params")

exports.apiv2 =  onRequest({minInstances: 2}, app)

// currently running after every 10 mins
exports.callUploadAfterEveryXmin = onSchedule("*/10 * * * *", async() => {
   ...
})

/**
 * When an image is uploaded in the Storage bucket,
 * generate a preview image automatically using sharp.
 * This code creates a 600x300 preview image for the 
 * image saved in a temporary directory, then uploads 
 * it back to Cloud Storage.
 */
exports.generatePreviewImg = onObjectFinalized(async (event) => {

    const fileBucket = event.data.bucket; // Storage bucket containing the file.
    const filePath = event.data.name; // File path in the bucket.
    const contentType = event.data.contentType; // File content type.
  
    // Exit if this is triggered on a file that is not an image.
    if (!contentType.startsWith("image/")) {
      return logger.log("This is not an image.");
    }
    // Exit if the image is already a preview image.
    const fileName = path.basename(filePath);
    if (fileName.startsWith("preview_")) {
      return logger.log("Already a Preview Image.");
    }
  
    // Download file into memory from bucket.
    const bucket = getStorage().bucket(fileBucket);
    const downloadResponse = await bucket.file(filePath).download();
    const imageBuffer = downloadResponse[0];
    logger.log("Image downloaded!");
  
    // Generate a preview image using sharp.
    const previewBuffer = await sharp(imageBuffer).resize({
      width: 600,
      height: 300,
      withoutEnlargement: true,
    }).toBuffer();
    logger.log("preview image created");
  
    // Prefix 'preview_' to file name.
    const thumbFileName = `preview_${fileName}`;
    const thumbFilePath = path.join(path.dirname(filePath), thumbFileName);
  
    // Upload the preview image.
    const metadata = {contentType: contentType};
    await bucket.file(thumbFilePath).save(previewBuffer, {
      metadata: metadata,
    });
    return logger.log("Preview image uploaded!");
  });

部署配置信息

package.json

"scripts": {
    "deploy:prod": "npm run changeToProd && firebase deploy",
    "changeToProd": "firebase use prod"
}

.firebaserc

{
  "projects": {
    "default": "dummy-dev",
    "dev": "dummy-dev",
    "prod": "dummy-prod"
  }
}

解决方案

核心原因

Firebase CLI尝试自动配置触发onObjectFinalized所需的IAM权限时失败,因为Cloud Functions Admin和Editor角色没有项目级IAM策略修改权限,无法为相关服务账号添加必要角色。

解决步骤

  1. 手动配置IAM权限:执行错误提示中的4条gcloud命令,给对应服务账号添加角色:

    gcloud projects add-iam-policy-binding zipshot-prod --member=serviceAccount:service-1090842465135@gs-project-accounts.iam.gserviceaccount.com --role=roles/pubsub.publisher
    gcloud projects add-iam-policy-binding zipshot-prod --member=serviceAccount:service-1090842465135@gcp-sa-pubsub.iam.gserviceaccount.com --role=roles/iam.serviceAccountTokenCreator
    gcloud projects add-iam-policy-binding zipshot-prod --member=serviceAccount:1090842465135-compute@developer.gserviceaccount.com --role=roles/run.invoker
    gcloud projects add-iam-policy-binding zipshot-prod --member=serviceAccount:1090842465135-compute@developer.gserviceaccount.com --role=roles/eventarc.eventReceiver
    

    执行前确保已通过gcloud auth login登录有权限修改项目IAM的账号。

  2. 使用项目所有者账号重新部署:切换到项目所有者权限的账号,重新运行npm run deploy:prod,Firebase CLI会自动完成IAM配置。

额外修复:部署警告处理

部署时出现的params.PROJECT_ID.value()警告,需检查代码中是否在部署阶段调用了projectID.value(),正确做法是直接使用projectID参数(如函数配置项),不要在部署时调用.value()方法,避免该警告。

内容的提问来源于stack exchange,提问作者ATOM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 09:59:55