可调用的云函数在Flutter中返回Null [英] Callable Cloud Functions Returning Null in Flutter

查看:194
本文介绍了可调用的云函数在Flutter中返回Null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标:

我想在我的 Flutter应用程序 中调用 Cloud Function ,该函数检索 JSON obj 来自 Python-FastAPI服务器 ,并在 Alert Dialogue 中显示内容.

My Goal:

I wish to call a Cloud Function in my Flutter App which retrieves a JSON obj from a Python-FastAPI server and displays content in Alert Dialogue.

错误:

我的flapp应用程序中的Callable Function Service收到null.我的警报对话框显示空值错误";由我的代码触发.

The Error:

The Callable Function Service within my flutter app recieves null. My alert dialog displays "Null Value Error" as triggered by my code.

  • 可调用的Http函数
  • 中从客户端(Flutter APP)接收数据
  • 调用Python API =>返回到返回给客户端的Cloud Function
  • Receive data from client (Flutter APP) in Callable Http Function
  • Call Python API => return to Cloud Function which returns to Client

云功能:

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),
    );
  }
}

注意 * 我想将密码检索保留为Cloud Function,因此它既可以在Web应用程序中使用,也可以在移动应用程序中使用.但是,如果有更好的解决方案,我愿意重构整个操作.

NOTE* I would like to keep the password retrieval as a Cloud Function, so it can be used on web-apps as well as mobile. I am however open to refactoring the entire operation if a better solution presents itself.

推荐答案

解决方案:

  • 将构造函数用于无状态小部件
  • 避免.then()
  • async函数中调用时,Cloud Functions应该返回Promise.resolve().

Solution:

  • Use Constructors for stateless widgets
  • avoid .then()
  • Cloud Functions should return Promise.resolve() when called in async function.

在按钮上单击:


    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));


为了便于阅读,我在上面的代码中删除了异常处理

For ease of reading I removed exception handling in the code above

显示警报对话框:


    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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆