Google 云函数:functions.https.onCall 返回 null 但值在日志中正确显示
Google cloud functions: functions.https.onCall returning null but the value is shown correctly in the logs
我正在通过 Axios async-await 调用第三方 API,并通过 google 云函数将结果返回给 flutter 应用程序。我被迫使用 functions.https.onCall
因为据我所知 flutter 不能调用 onRequest
函数。
结果在云函数的日志 console.log
中正确显示,但是当 flutter 应用程序调用该函数时,它总是接收 null
。为什么?
getSmsBalance: functions.https.onCall(async (data, context) => {
const business_id = data.business_id;
const collectionRef = db.collection("buser_sms");
const snapshot = await collectionRef.where("id", "==", business_id).get();
if (snapshot.empty) {
console.log("No matching documents - getSMSBalance .");
let response = {
status: false,
};
return JSON.stringify(response);
}
snapshot.forEach((doc) => {
if (
doc.data().enableReservationSms == true ||
doc.data().enableAutoReminder == true ||
doc.data().enableReminderSms == true
) {
// get balance
(async () => {
const balance = await getBalance(
doc.data().senderId,
doc.data().username,
doc.data().password
)
.then((result) => {
let response = {
status: true,
data: result,
};
console.log("balance is " + result);
return JSON.stringify(response);
})
.catch((err) => {
console.error(`Error - getSmsBalance - ${err}`);
let response = {
status: false,
};
return JSON.stringify(response);
});
})();
}
});
}),
您的代码存在几个问题:
- 您正在
Array.forEach
中使用 async/await 语法,由于其固有设计,它不允许等待。如果要在循环迭代中使用 async/await,则需要使用 Array.map
等。但在大多数情况下,您不应该在循环内使用 async/await,因为它消除了异步代码执行的优势(每次迭代仅在前一次迭代之后触发)。
- 除了
snapshot.empty
之外,您的函数中没有 return 任何内容。 then
和 catch
回调中的 return
仅将值分配给变量 balance
,之后不会使用该变量。
所以总而言之,您需要使用类似的东西:
return Promise.all(
snapshot.map((doc) => {
return getBalance(
doc.data().senderId,
doc.data().username,
doc.data().password
)
.then((result) => {
let response = {
status: true,
data: result,
};
console.log('balance is ' + result);
return JSON.stringify(response);
})
.catch((err) => {
console.error(`Error - getSmsBalance - ${err}`);
let response = {
status: false,
};
return JSON.stringify(response);
});
})
);
请注意,我提供的代码是截取的,没有考虑您实际需要的输出格式。拥有一个 response
数组可能不是您所需要的。但是您最终应该能够根据您的需要调整该代码。
我正在通过 Axios async-await 调用第三方 API,并通过 google 云函数将结果返回给 flutter 应用程序。我被迫使用 functions.https.onCall
因为据我所知 flutter 不能调用 onRequest
函数。
结果在云函数的日志 console.log
中正确显示,但是当 flutter 应用程序调用该函数时,它总是接收 null
。为什么?
getSmsBalance: functions.https.onCall(async (data, context) => {
const business_id = data.business_id;
const collectionRef = db.collection("buser_sms");
const snapshot = await collectionRef.where("id", "==", business_id).get();
if (snapshot.empty) {
console.log("No matching documents - getSMSBalance .");
let response = {
status: false,
};
return JSON.stringify(response);
}
snapshot.forEach((doc) => {
if (
doc.data().enableReservationSms == true ||
doc.data().enableAutoReminder == true ||
doc.data().enableReminderSms == true
) {
// get balance
(async () => {
const balance = await getBalance(
doc.data().senderId,
doc.data().username,
doc.data().password
)
.then((result) => {
let response = {
status: true,
data: result,
};
console.log("balance is " + result);
return JSON.stringify(response);
})
.catch((err) => {
console.error(`Error - getSmsBalance - ${err}`);
let response = {
status: false,
};
return JSON.stringify(response);
});
})();
}
});
}),
您的代码存在几个问题:
- 您正在
Array.forEach
中使用 async/await 语法,由于其固有设计,它不允许等待。如果要在循环迭代中使用 async/await,则需要使用Array.map
等。但在大多数情况下,您不应该在循环内使用 async/await,因为它消除了异步代码执行的优势(每次迭代仅在前一次迭代之后触发)。 - 除了
snapshot.empty
之外,您的函数中没有 return 任何内容。then
和catch
回调中的return
仅将值分配给变量balance
,之后不会使用该变量。
所以总而言之,您需要使用类似的东西:
return Promise.all(
snapshot.map((doc) => {
return getBalance(
doc.data().senderId,
doc.data().username,
doc.data().password
)
.then((result) => {
let response = {
status: true,
data: result,
};
console.log('balance is ' + result);
return JSON.stringify(response);
})
.catch((err) => {
console.error(`Error - getSmsBalance - ${err}`);
let response = {
status: false,
};
return JSON.stringify(response);
});
})
);
请注意,我提供的代码是截取的,没有考虑您实际需要的输出格式。拥有一个 response
数组可能不是您所需要的。但是您最终应该能够根据您的需要调整该代码。