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

Firebase Functions部署Stripe验证会话遇启动失败求助

问题:Firebase Functions(Node.js 18 第二代)部署Stripe身份验证会话函数失败

错误现象

部署时出现以下错误:

i functions: updating Node.js 18 (2nd Gen) function createVerificationSession(us-central1)...
Could not create or update Cloud Run service createverificationsession, Container Healthcheck failed. Revision 'createverificationsession-00014-jow' is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable. Logs for this revision might contain more information.

关键日志信息

日志1:Stripe授权错误

{  
  "textPayload": "    StripeInvalidGrantError: [class StripeInvalidGrantError extends StripeError],",
  "insertId": "663fc892000d43eabf84f867",
  [...]
  "logName": "projects/lectio-c2268/logs/run.googleapis.com%2Fstdout",
  "receiveTimestamp": "2024-05-11T19:35:47.208375619Z"
}

日志2:端口健康检查失败

{  
  "textPayload": "Default STARTUP TCP probe failed 1 time consecutively for container \"worker\" on port 8080. The instance was not started.",
  "insertId": "663fc893000cef0fae764d6a",
  [...]
}

相关代码与配置

Firebase Functions代码

const { onCall } = require('firebase-functions/v2/https');
const { error } = require('firebase-functions/logger');
import admin = require('firebase-admin');const functions = require('firebase-functions');
const stripe = require('stripe')(
'sk_test_51O7T...',
);

[...]

exports.createVerificationSession = onCall(async (data: any, context: any) => {
  const verificationSession = await stripe.identity.verificationSessions.create(
    {
      type: 'document',
      metadata: {
        user_id: context.auth.uid,
      },
    },
  );
  const clientSecret = verificationSession.client_secret;
  console.log('Client secret:', clientSecret);
  return { clientSecret };
});

前端调用代码

const stripePromise = loadStripe(
'pk_live_51O7...',
); 

function Payment() {
  const [clientSecret, setClientSecret] = useState('');

  useEffect(() => {
    const fetchClientSecret = async () => {
      console.log('Fetching client secret');
      const functions = getFunctions();
      const createVerificationSession = httpsCallable(
        functions,
        'createVerificationSession',
      );

      try {
        console.log('Calling createVerificationSession');
        await createVerificationSession().then((result) => {
          console.log('Result:', result);
        });
        // setClientSecret(response.data.clientSecret);
      } catch (error) {
        console.error('Failed to fetch client secret:', error);
        // Handle errors here appropriately
      }
    };

    fetchClientSecret();
  }, []);

  if (!stripePromise || !clientSecret) {
    return <p>Loading payment details...</p>;
  }

  const options = {
    clientSecret: clientSecret,
  };

  return (
    <Elements stripe={stripePromise} options={options}>
      <CheckoutForm />
    </Elements>
  );
}

export default Payment;

firebase.json配置

{  
  "functions": {
    "source": "../../functions",
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint",
      "npm --prefix \"$RESOURCE_DIR\" run build"
    ]
  },
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "emulators": {
    "auth": {
      "port": 9099
    },
    "firestore": {
      "port": 8080
    },
    "functions": {
      "port": 5001
    },
    "ui": {
      "enabled": true
    },
    "singleProjectMode": true
  }
}

解决步骤

1. 修复Stripe API密钥问题

StripeInvalidGrantError直接指向密钥无效:

  • 确认密钥类型:测试环境必须用sk_test_开头的测试密钥,生产环境用sk_live_密钥
  • 检查密钥完整性:复制时是否遗漏字符,登录Stripe后台确认密钥未被禁用/删除
  • 不要硬编码密钥,改用Firebase环境变量存储:
    firebase functions:config:set stripe.secret="sk_test_your_full_key"
    
    代码中读取方式改为:
    const stripe = require('stripe')(functions.config().stripe.secret);
    

2. 解决端口冲突

第二代Functions默认监听PORT环境变量指定的端口(默认8080),但你的Firestore模拟器也占用了8080,导致启动失败:

  • 修改firebase.json中Firestore模拟器端口,比如改为8081:
    "emulators": {
      "auth": { "port": 9099 },
      "firestore": { "port": 8081 },
      "functions": { "port": 5001 },
      "ui": { "enabled": true },
      "singleProjectMode": true
    }
    
  • 重启所有模拟器,确保端口无冲突

3. 代码语法与依赖检查

  • 代码中混合了require和import(import admin = require('firebase-admin');),Node.js 18 CommonJS模式下改为统一写法:
    const admin = require('firebase-admin');
    
  • 确认functions目录下package.json已安装所有依赖:firebase-admin、firebase-functions、stripe,版本需兼容Node.js 18
  • 运行npm run build确保编译无错误,检查predeploy脚本执行正常

4. 本地调试验证

  • 单独启动函数模拟器测试:
    firebase emulators:start --only functions
    
  • 通过Firebase Emulator UI(默认http://localhost:4000)调用createVerificationSession,确认能正常返回clientSecret
  • 查看本地函数日志,确认无Stripe相关错误

5. 部署前最后检查

  • 确认当前使用的Firebase项目正确:firebase use your-project-id
  • 清理Cloud Run旧版本残留,避免影响新部署
  • 带debug参数部署,查看详细日志:
    firebase deploy --only functions:createVerificationSession --debug
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:34:59