微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

flutter_graphql 不起作用,并且在应用构建后始终返回 null

如何解决flutter_graphql 不起作用,并且在应用构建后始终返回 null

我是 Flutter 和 graphql 的新手 我正在尝试开发一个应用程序来使用 heroku 上托管的后端 api 在开发过程中以及在我的三星 Note 5 上测试应用程序时,应用程序成功连接到后端,我可以从查询和突变中获取数据 但是在构建 app-release.apk 并将其安装在同一台手机上之后,查询和突变中的响应始终为空。 另外,我在后端有 REST api,我使用 dio lib 发送请求,但我没有从这些请求中得到任何响应。 我试过“扑干净”但徒劳无功 Flutter doctor 命令显示没有错误

Doctor summary (to see all details,run Flutter doctor -v):
[√] Flutter (Channel stable,2.0.3,on Microsoft Windows [Version 10.0.18363.1646],locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[√] Chrome - develop for the web
[√] Android Studio
[√] VS Code (version 1.54.3)
[√] Connected device (2 available)

• No issues found!

我使用的是 android studio 4.2.2

main.dart

bool isAuth;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initHiveForFlutter();
  isAuth = await isAuthenticated();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GraphQLProvider(
      client: client,child: MaterialApp(
          debugShowCheckedModeBanner: false,title: 'Flutter App',theme: ThemeData(
            primarySwatch: Colors.red,),initialRoute: isAuth ? 'HomeScreen' : 'LoginScreen',routes: {
            'HomeScreen': (context) => HomeScreen(),'LoginScreen': (context) => LoginScreen()
          }),);
  }
}

身份验证.dart

// check if token is set using sharedPreferences lib
Future<bool> isAuthenticated() async {
  final accesstoken = await getAccesstoken(); 
  if (accesstoken != null) {
    return true;
  }
  return false;
}

GraphQLConfiguration.dart:

class GraphQLConfiguration {

  HttpLink _httpLink;
  AuthLink _authLink;
  Link _link;

  GraphQLConfiguration () {
    _httpLink = new HttpLink('https://backendapi.herokuapp.com/graphql');
    _authLink = new AuthLink(getToken: () async => 'Bearer ${await getAccesstoken()}');
    _link = _authLink.concat(_httpLink);
  }

  GraphQLClient myGQLClient() {
    return GraphQLClient(
      link: _link,cache: GraphQLCache(store: HiveStore()),);
  }
}
ValueNotifier<GraphQLClient> client = ValueNotifier(GraphQLConfiguration().myGQLClient());

mutations.dart

String login() {
    return '''
      mutation login(\$data: LoginInput!){
        login(data: \$data){
          status
          message
          accesstoken
        } 
      }
    ''';
  }

登录屏幕.dart


class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  bool _hidePassword = true;

  final TextEditingController _usernameController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizetoAvoidBottomInset: false,body: Stack(
        children: [
          Mutation(
            options: Mutationoptions(
                document: gql(mutations.login()),update: (GraphQLDataProxy cache,QueryResult result) {
                  String cookie;
                  final String cookieHeader = result.context
                      .entry<HttpLinkResponseContext>()
                      .headers['set-cookie'];
                  if (cookieHeader != null) {
                    cookie = cookieHeader.split(';')[0];
                  }

                  final LoginResponse loginResponse =
                      LoginResponse.from(result.data['login']);

                  if (loginResponse.status == true && cookie != null) {
                    setRefreshToken(cookie);
                  }
                  return cache;
                },onCompleted: (resultData) async {
                  final LoginResponse loginResponse =
                      LoginResponse.from(resultData['login']);
                  if (loginResponse.status == true) {
                    await setAccesstoken(loginResponse.accesstoken);
                    Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => HomeScreen()));
                  }
                  Fluttertoast.showToast(
                    msg: loginResponse.message,backgroundColor: Colors.grey,gravity: ToastGravity.BottOM,fontSize: 16.0,timeInSecForIosWeb: 1,textColor: Colors.white,toastLength: Toast.LENGTH_LONG,);
                }),builder: (RunMutation runMutation,QueryResult result) {
              return Column(
                mainAxisSize: MainAxisSize.max,mainAxisAlignment: MainAxisAlignment.spaceBetween,crossAxisAlignment: CrossAxisAlignment.stretch,children: [
                  Container(
                    margin: EdgeInsets.only(top: 100),child: Column(
                      children: [
                        Text(
                          'Welcome...',style: TextStyle(
                            shadows: [
                              Shadow(
                                offset: Offset(0.5,0.5),blurRadius: 10.0,color: Colors.grey,],fontSize: 45,letterSpacing: 2,fontWeight: FontWeight.bold,Text(
                          'welcome,',style: TextStyle(
                            fontSize: 20,letterSpacing: 7,)
                      ],Container(
                    child: Column(
                      children: [
                        Padding(
                          padding:
                              EdgeInsets.symmetric(vertical: 0,horizontal: 20),child: TextField(
                            controller: _usernameController,style: TextStyle(
                              fontSize: 22.0,decoration: Inputdecoration(
                              labelText: 'Username',border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(50.5),prefixIcon:
                                  Icon(Icons.supervised_user_circle_outlined),Padding(
                          padding: EdgeInsets.symmetric(
                              vertical: 10,child: TextField(
                            controller: _passwordController,obscureText: _hidePassword,decoration: Inputdecoration(
                              labelText: 'Password',prefixIcon: Icon(Icons.lock),suffixIcon: IconButton(
                                icon: Icon(_hidePassword
                                    ? Icons.visibility
                                    : Icons.visibility_off),onpressed: () => _togglePasswordVisibility(),Padding(
                          padding: EdgeInsets.only(top: 30),child: ElevatedButton(
                            style: ButtonStyle(
                              padding: MaterialStateProperty.all<EdgeInsets>(
                                  EdgeInsets.all(15)),minimumSize:
                                  MaterialStateProperty.all<Size>(Size(370,0)),shape: MaterialStateProperty.all<
                                  RoundedRectangleBorder>(
                                RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(50.0),side: BorderSide(color: Colors.red),backgroundColor:
                                  MaterialStateProperty.all<Color>(Colors.red),onpressed: () => runMutation(
                              {
                                'data': {
                                  'username': _usernameController.text,'password': _passwordController.text
                                }
                              },child: Text(
                              'Login',style: TextStyle(
                                fontSize: 30.0,Container(
                    margin: EdgeInsets.only(top: 100),padding: EdgeInsets.only(bottom: 20),child: Center(
                      child: Text(
                        'BY XXX',style: TextStyle(
                          color: Colors.grey,fontSize: 10,);
            },);
  }

  void _togglePasswordVisibility() {
    setState(() {
      _hidePassword = !_hidePassword;
    });
  }

pubspec.yaml


environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  Flutter:
    sdk: Flutter
  graphql_Flutter: ^5.0.0
  shared_preferences: ^2.0.6
  http: ^0.13.3
  Fluttertoast: ^8.0.7
  font_awesome_Flutter: ^9.1.0
  dio: ^4.0.0
  Flutter_datetime_picker: ^1.5.1
  loading_overlay: ^0.3.0

  cupertino_icons: ^1.0.2


dev_dependencies:
  Flutter_test:
    sdk: Flutter

Flutter:

  uses-material-design: true


  assets:
     - assets/images/male.png
     - assets/images/female.png

  fonts:
    - family: Changa
      fonts:
        - asset: fonts/Changa-Regular.ttf
        - asset: fonts/Changa-Bold.ttf
          weight: 700

解决方法

正如我所说,我是 Flutter 和移动应用程序开发的新手 并且解决方案是从这个 thread

问题与 flutter_graphql lib 无关,而是与 android 项目的清单文件有关。 应声明互联网许可。 我以为 Flutter 会根据使用的库自动检测和配置应用权限,但我错了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。