Firebase 在flatter中返回Null的可调用云函数 我的目标是:
我希望在我的flatter应用程序中调用云函数,该函数从Python FastAPI服务器检索JSON obj,并在警报对话框中显示内容 错误: 我的颤振应用程序中的可调用函数服务接收空值。我的警报对话框显示由我的代码触发的“空值错误” 云端操作: 我的云功能分为两部分:Firebase 在flatter中返回Null的可调用云函数 我的目标是:,firebase,flutter,google-cloud-functions,flutter-web,Firebase,Flutter,Google Cloud Functions,Flutter Web,我希望在我的flatter应用程序中调用云函数,该函数从Python FastAPI服务器检索JSON obj,并在警报对话框中显示内容 错误: 我的颤振应用程序中的可调用函数服务接收空值。我的警报对话框显示由我的代码触发的“空值错误” 云端操作: 我的云功能分为两部分: 在可调用的Http函数中从客户端(颤振应用程序)接收数据 调用pythonapi=>returntocloud函数,返回给客户端 云功能: exports.getRandomPassword = functions.ht
- 在可调用的Http函数中从客户端(颤振应用程序)接收数据
- 调用pythonapi=>returntocloud函数,返回给客户端
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});
});
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;
}
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());
},
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),
);
}
}
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>;
}
Python FastAPI调用:
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});
});
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;
}
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());
},
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),
);
}
}
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>;
}
我的颤振获取密码()函数:
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});
});
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;
}
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());
},
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),
);
}
}
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>;
}
注意*
我想将密码检索保留为一种云功能,这样它就可以在web应用程序和移动应用程序上使用。不过,如果有更好的解决方案出现,我愿意重构整个操作
解决方案:
- 对无状态小部件使用构造函数
- 避免
。然后()
- 在
函数中调用云函数时,应该返回async
Promise.resolve()
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});
});
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;
}
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());
},
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),
);
}
}
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>;
}
云功能:
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});
});
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;
}
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());
},
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),
);
}
}
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>;
}
exports.getRandomPassword=functions.https.onCall(异步(数据、上下文)=>{
const usesymbles=data.usesymbles;
const pwLength=data.pwLength;
输入密码;
密码=等待调用API(pwLength,useSymbers);
常量调试={
接收数据类型:数据类型,
接收到的数据:数据,
pwLen_类型:pwLength的类型,
pwLength,
使用符号类型:使用符号的类型,
使用符号,
ResultingPayloadType:密码类型,
结果有效负载:密码,
}
日志(调试);
返回承诺。解析(密码)
});
异步函数callAPI(pwLength:any,useSymbers:any){
//使用参数生成URL字符串
const ROOT_URL=`http://[My_Api_IP_Address]/password?pwd_length=${pwdlength}&use_symbols=${usesymmbols}`;
const res=wait http.get(ROOT\u URL);
log(res.getBody());
返回res.getBody()作为映射;
}
也许我因为文章太长而错过了它,但问题是什么?什么不起作用?正如标题所示,云函数返回null。我将更新问题,以便更好地解释这一点。