在 Flutter 中返回 Null 的可调用云函数
Posted
技术标签:
【中文标题】在 Flutter 中返回 Null 的可调用云函数【英文标题】:Callable Cloud Functions Returning Null in Flutter 【发布时间】:2021-01-24 21:21:23 【问题描述】:我的目标:
我希望在我的 Flutter App 中调用 Cloud Function 来检索 JSON obj 来自 Python-FastAPI 服务器,并在警报对话框中显示内容。
错误:
我的颤振应用程序中的可调用函数服务收到 null。我的警报对话框显示由我的代码触发的“空值错误”。
云端操作:
我的云功能分为两部分:
在Callable Http Function中从客户端(Flutter APP)接收数据 调用 Python API => 返回云函数,返回客户端
云功能:
exports.getRandomPassword = functions.https.onCall(async (data, context) =>
const useSymbols = data.useSymbols;
const pwLength= data.pwLength;
const debug =
received_data_type: typeof data,
received_data:data,
pwLen_type: typeof pwLength,
pwLength,
useSymbols_type:typeof useSymbols,
useSymbols,
console.log(debug);
await callAPI(pwLength,useSymbols).then((res:any) =>
console.log(`Resulting Payload: $res`);
return res);
);
Python-FastAPI 调用:
async function callAPI(pwLength: any, useSymbols: any)
// BUILD URL STRING WITH PARAMS
const ROOT_URL = `http://[IP_Address]/password?pwd_length=$pwLength&use_symbols=$useSymbols`;
let res;
// let password: any; // password to be received
await http.get(ROOT_URL)
.then((response: any) =>
console.log("TO APP "+JSON.stringify(response));
console.log(response.getBody());
res = response.getBody() as Map<any, any>;
)
.catch((err: any) =>
console.log(err);
res= err;
);
return res;
生成的有效负载可以正常工作,如我的日志中所示:
客户端操作:
在 Flutter 中点击按钮:
onPressed: () async
// call cloud function & use set state to store pw
await getPassword().then((String result)
setState(()
password = result;
);
);
showDialog(
context: context,
builder: (context) => DisplayPassword());
,
我的 Flutter getPassword() 函数:
Future<String> getPassword() async
var pw;
final HttpsCallable callable = new CloudFunctions()
.getHttpsCallable(functionName: 'getRandomPassword')
..timeout = const Duration(seconds: 30);
try
await callable.call(
<String, dynamic>
'pwLength': 10,
'useSymbols': true,
,
).then((value)
print(value.data);
print(value.data.runtimeType);
pw = value.data;
return pw;
);
on CloudFunctionsException catch (e)
print('caught firebase functions exception');
print('Code: $e.code\nmessage: $e.message\ndetails: $e.details');
return '$e.details';
catch (e)
print('caught generic exception');
print(e);
return 'caught generic exception\n$e';
我的显示密码功能:
class DisplayPassword extends StatelessWidget
final String pw = (_MyPasswordGenPageState().password == null)
? 'null value error'
: _MyPasswordGenPageState().password;
@override
Widget build(BuildContext context)
return AlertDialog(
title: Text(pw),
);
注意* 我想将密码检索保留为云功能,因此它可以在网络应用程序和移动设备上使用。但是,如果出现更好的解决方案,我愿意重构整个操作。
【问题讨论】:
也许我因为帖子的长度而错过了它,但问题是什么?什么不工作? 正如标题所示,云函数返回 null。我将更新问题以更好地解释这一点。 【参考方案1】:解决方案:
为无状态小部件使用构造函数 避免.then()
Cloud Functions 在async
函数中调用时应返回Promise.resolve()
。
点击按钮:
dynamic result =
await callable.call(<String, dynamic>
'pwLength': 10,
'useSymbols': true,
//await the result before continuing
);
setState(()
// convert hashmap to list and get first val
password = result.data.values.toList()[0];
isLoading = false; // remove loading indicator
);
showDialog(
context: context,
builder: (context) =>
DisplayPassword(password));
为了便于阅读,我在上面的代码中删除了异常处理
显示警报对话框:
class DisplayPassword extends StatelessWidget
var password; // check if null
DisplayPassword(this.password); // constructor
@override
Widget build(BuildContext context)
// make sure null value isn't being passed to alert dialog widget
if (password == null)
password = 'null value error';
return AlertDialog(
title: Text(password),
);
云功能:
exports.getRandomPassword = functions.https.onCall(async (data, context) =>
const useSymbols = data.useSymbols;
const pwLength= data.pwLength;
let password;
password = await callAPI(pwLength,useSymbols);
const debug =
received_data_type: typeof data,
received_data:data,
pwLen_type: typeof pwLength,
pwLength,
useSymbols_type:typeof useSymbols,
useSymbols,
ResultingPayloadType: typeof password,
ResultingPayload: password,
console.log(debug);
return Promise.resolve(password)
);
async function callAPI(pwLength: any, useSymbols: any)
// BUILD URL STRING WITH PARAMS
const ROOT_URL = `http://[My_Api_IP_Address]/password?pwd_length=$pwLength&use_symbols=$useSymbols`;
const res = await http.get(ROOT_URL);
console.log(res.getBody());
return res.getBody() as Map<String , any>;
【讨论】:
以上是关于在 Flutter 中返回 Null 的可调用云函数的主要内容,如果未能解决你的问题,请参考以下文章