我是 Flutter 和 graphql 的新手我正在尝试开发一个应用程序以在开发期间使用托管在 heroku 上的后端 api,并且在我的三星 Note 5 上测试该应用程序时,该应用程序成功连接到后端,我可以从查询中获取数据和突变,但是在构建 app-release.apk 并将其安装在同一移动设备上之后,查询和突变的响应始终为空。此外,我在后端有 REST api,我使用 Dio lib 发送请求,但我没有从这些请求中得到任何响应。我尝试了“flutter clean”,但徒劳地颤动医生命令显示没有错误:
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!
我正在使用安卓工作室 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());
突变.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, horizontal: 20),
child: TextField(
controller: _passwordController,
obscureText: _hidePassword,
style: TextStyle(
fontSize: 22.0,
),
decoration: InputDecoration(
labelText: 'Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50.5),
),
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,
fontWeight: FontWeight.bold,
fontSize: 10,
),
),
),
),
],
);
},
),
],
),
);
}
void _togglePasswordVisibility() {
setState(() {
_hidePassword = !_hidePassword;
});
}
发布规范.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