Cloud Function解析Webhook的JSON失败无法写入Cloud Firestore问题求助
问题排查与解决步骤
1 报错根因定位
你看到的TypeError: Cannot read property 'email' of undefined报错,核心是payload.billing为undefined,说明req.body未被正确解析为预期的JSON结构,或者请求本身不存在有效body。
2 分步排查方案
2.1 增加请求合法性校验,过滤非POST请求
云函数会接收所有类型的HTTP请求,包括跨域预检的OPTIONS请求,这类请求无body,会直接触发报错。在函数最开头增加请求方法校验:
if (req.method !== 'POST') { return res.status(405).send('Method Not Allowed'); }
2.2 手动兼容JSON解析逻辑
GCP云函数仅在请求头Content-Type为application/json时会自动解析req.body为对象,如果Webhook发送的请求头不符合规范,req.body会是字符串或Buffer类型,需要手动解析:
console.log('Content-Type:', req.get('Content-Type')); console.log('Raw body content:', JSON.stringify(req.body)); let payload = req.body; // 兼容字符串类型的JSON body if (typeof payload === 'string') { try { payload = JSON.parse(payload); } catch (parseErr) { console.error('JSON解析失败:', parseErr); return res.status(400).send('Invalid JSON payload'); } }
2.3 增加字段存在性校验,避免崩溃
在读取billing下的字段前,先校验字段是否存在,从根源避免读取undefined属性的报错:
if (!payload || !payload.billing || !payload.billing.email) { console.error('缺少必填字段,收到的payload:', payload); return res.status(400).send('Missing required billing fields'); }
2.4 正确捕获异步操作错误
你之前加的catch未正确包裹异步逻辑,会触发未处理的Promise rejection,改用try/catch包裹Firestore写入逻辑:
try { await admin.firestore().collection("people").doc().set({ people_Email: payload.billing.email, people_FirstName: payload.billing.first_name, people_LastName: payload.billing.last_name, }); return res.status(200).end(); } catch (dbErr) { console.error('Firestore写入失败:', dbErr); return res.status(500).send('Internal server error'); }
3 最终完整可运行代码
const admin = require('firebase-admin') admin.initializeApp(); exports.wooCommerceWebhook = async (req, res) => { // 1. 仅允许POST请求 if (req.method !== 'POST') { return res.status(405).send('Method Not Allowed'); } // 2. 解析并校验payload console.log('Content-Type:', req.get('Content-Type')); console.log('Raw body content:', JSON.stringify(req.body)); let payload = req.body; if (typeof payload === 'string') { try { payload = JSON.parse(payload); } catch (parseErr) { console.error('JSON解析失败:', parseErr); return res.status(400).send('Invalid JSON payload'); } } // 3. 校验必填字段 if (!payload || !payload.billing || !payload.billing.email) { console.error('缺少必填字段,收到的payload:', payload); return res.status(400).send('Missing required billing fields'); } // 4. 写入Firestore并捕获错误 try { await admin.firestore().collection("people").doc().set({ people_Email: payload.billing.email, people_FirstName: payload.billing.first_name, people_LastName: payload.billing.last_name, }); return res.status(200).end(); } catch (dbErr) { console.error('Firestore写入失败:', dbErr); return res.status(500).send('Internal server error'); } };
4 后续验证
部署修改后的代码后触发Webhook,查看云函数日志,打印的Content-Type和raw body内容可以帮你进一步定位是否是Webhook请求格式异常。
内容的提问来源于stack exchange,提问作者Stephen Stilwell
相关产品推荐
相关产品推荐

