Firebase Cloud Functions onCall调用异常:data与context均为undefined
Firebase可调用函数onCall出现data/context为undefined的问题排查
环境信息
- Firebase CLI版本:12.4.0
- Firebase Unity版本:11.2.0(最新)
- Unity版本:2022.2.17
问题现象
调用Firebase可调用函数时,服务器端抛出以下错误:
Unhandled error TypeError: Cannot read properties of undefined (reading 'auth') at /workspace/index.js:17:16 at fixedLen (/workspace/node_modules/firebase-functions/lib/v2/providers/https.js:118:31) at /workspace/node_modules/firebase-functions/lib/common/providers/https.js:467:32 at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
调试发现服务器端的data和context均为undefined,日志输出全为Undefined,但Unity客户端已确认数据正确传递且用户已登录,同时onRequest功能正常,说明项目配置无问题。
服务器端代码(原错误版本)
const {onRequest, onCall, HttpsError} = require("firebase-functions/v2/https"); const {initializeApp} = require("firebase-admin/app"); initializeApp(); exports.onLoginAddOTPEntry = onCall((data, context) => { console.log(data.otp); console.log(data.email); console.log(context); if (!data || !data.email || !data.otp) { throw new HttpsError("invalid-argument", "onLoginAddOTPEntry should be called with email and otp"); } if (!context.auth) { throw new HttpsError( "unauthorized", "User is not authenticated", ); } return "Worked!"; });
Unity客户端代码
private FirebaseFunctions firebaseFunctions; public void Initialize() { firebaseFunctions = FirebaseFunctions.DefaultInstance; } public async void CallableFunction(string functionName, KeyValuePair<string, string>[] dataToPass, Action<bool, string, string> _onSuccess) { var function = firebaseFunctions.GetHttpsCallable(functionName); // pass data if (dataToPass?.Length > 0) { var data = new Dictionary<string, object>(); for (int i = 0, count = dataToPass.Length; i < count; ++i) { data.Add(dataToPass[i].Key, dataToPass[i].Value); } await function.CallAsync(data).ContinueWith((task) => { Debug.Log("Task: " + task.ToJSON()); }); return; } await function.CallAsync().ContinueWith((task) => { Debug.Log("Task: " + task.ToJSON()); }); }
问题原因及解决方案
问题出在Firebase Functions v2的onCall API签名与v1不兼容:
- v1版本中,
onCall的回调函数接收两个独立参数data和context - v2版本中,
onCall的回调函数仅接收一个request对象,data和用户认证信息auth都嵌套在这个对象里
修改服务器端代码,调整参数解构方式即可解决:
const {onRequest, onCall, HttpsError} = require("firebase-functions/v2/https"); const {initializeApp} = require("firebase-admin/app"); initializeApp(); exports.onLoginAddOTPEntry = onCall((request) => { // 从request对象中解构data和auth const { data, auth } = request; console.log(data.otp); console.log(data.email); console.log(auth); if (!data || !data.email || !data.otp) { throw new HttpsError("invalid-argument", "onLoginAddOTPEntry should be called with email and otp"); } if (!auth) { throw new HttpsError( "unauthorized", "User is not authenticated", ); } return "Worked!"; });
如果需要配置CORS等选项,也可以通过第一个参数传入配置对象:
exports.onLoginAddOTPEntry = onCall({ cors: true }, (request) => { const { data, auth } = request; // 后续逻辑不变 });
内容的提问来源于stack exchange,提问作者eagle
相关产品推荐
相关产品推荐

