Swift iOS调用Firebase Cloud Function无法传递请求参数问题求解
问题原因
- 两种Firebase云函数触发模式不匹配:
- 服务端当前使用的是普通HTTP触发函数,通过
functions.https.onRequest定义,需要完全匹配自定义的HTTP请求格式 - iOS端使用的
httpsCallableAPI是专为可调用云函数(functions.https.onCall定义)设计的,会自动对请求、响应做封装,和当前服务端的预期协议存在差异
- 若保持当前服务端逻辑不变,参数结构需要对齐你在API测试工具中验证通过的格式:请求体外层需要用
data键包裹实际业务参数,当前iOS端传递的参数缺少外层data包装,导致服务端读取request.body.data.attributionID时无法取到对应值。
修复方案
方案一:服务端适配可调用函数协议(推荐)
直接将服务端改为可调用云函数,不用修改现有iOS端的参数传递逻辑,还能自动继承Firebase的用户鉴权、防CSRF等能力:
exports.numberOfVideos = functions.https.onCall((data, context) => { // 可直接读取传入的参数,不需要解析request.body const attributionID = data.attributionID || "No attributionID found."; functions.logger.info('[LOG]: 收到的attributionID为 ' + attributionID, {structuredData: true}); const db = admin.firestore(); return db.collection("content").get().then(snapshot => { let total = 0; snapshot.forEach(doc => { if (doc.data().attributionID == attributionID) { total++; } }); // 直接返回数据即可,框架会自动封装为符合要求的响应格式 return { attributionID: attributionID, numberOfContents: total.toString() }; }).catch(reason => { throw new functions.https.HttpsError('unknown', reason.message, reason); }) });
方案二:保持服务端不变,修改iOS端参数结构
如果不需要使用可调用函数的额外能力,仅需要匹配现有服务端的HTTP协议,只需要在iOS端传参时外层包裹data键即可:
将原有调用代码
httpsCallable.call(["attributionID" : obj.id])
修改为:
httpsCallable.call(["data": ["attributionID" : obj.id]])
补充排查建议
你可以直接查看服务端打印的request.body日志,确认iOS端发送的实际请求体结构,就能快速定位参数所在的层级是否符合预期。
内容的提问来源于stack exchange,提问作者David Reese
相关产品推荐
相关产品推荐

