Flutter注册成功(数据库已存数据)但页面无法跳转问题求助
问题:Flutter注册成功后无法跳转首页(接口返回200但AuthProvider返回false)
注册数据已成功存入数据库,接口响应状态码为200,但页面无法跳转至首页,控制台报错type 'Null' is not a subtype of type 'String',相关代码及日志如下:
register_page.dart 核心代码
Widget build(BuildContext context) { AuthProvider authProvider = Provider.of<AuthProvider>(context); handleRegister() async { print('handleRegister() called'); if (await authProvider.register( name: nameController.text, username: usernameController.text, email: emailController.text, password: passwordController.text)) { print('register() returned true'); Navigator.pushNamed(context, '/home'); } else { print('register() returned false'); } } Widget button(){ return Container( height: 50, width: double.infinity, margin: const EdgeInsets.only(top: 30), child: TextButton( onPressed: handleRegister, style: TextButton.styleFrom( backgroundColor: primaryColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12) ) ), child: Text("Sign Up", style: primaryTextStyle.copyWith( fontSize: 16, fontWeight: medium ), ), ), ); } // ...其他代码 }
authservice.dart 核心代码
class AuthService { String baseUrl = "http://192.168.100.229:8000/api"; Future<UserModel> register( {required String name, required String username, required String email, required String password}) async { var url = '$baseUrl/register'; var headers = {'Content-Type': 'application/json'}; var body = jsonEncode({ 'name': name, 'username': username, 'email': email, 'password': password }); var response = await http.post(Uri.parse(url), headers: headers, body: body); log('code ${response.statusCode} '); log('status : ${response.statusCode == 200? true : false}'); if (response.statusCode == 200) { var data = jsonDecode(response.body)['data']; UserModel user = UserModel.fromJson(data['user']); user.token = data['token_type'] + " " + data['access_token']; log("register success"); return user; } else { log("register fail"); throw Exception("register failed"); } } }
authprovider.dart 核心代码
class AuthProvider with ChangeNotifier { late UserModel _user; UserModel get user => _user; set user(UserModel user) { _user = user; notifyListeners(); } Future<bool> register( {required String name, required String username, required String email, required String password}) async { try { UserModel user = await AuthService().register( name: name, username: username, email: email, password: password); _user = user; log("auth provider true"); return true; } catch (e) { log("auth provider false", error: e); return false; } } }
控制台日志
I/flutter ( 6788): handleRegister() called I/flutter ( 6788): register() returned false [log] auth provider false type 'Null' is not a subtype of type 'String'
解决方案
1. 定位空值来源
报错type 'Null' is not a subtype of type 'String'说明在字符串拼接或JSON解析时,某个预期为String的字段实际是Null,结合代码分析:
- 拼接token时,
data['token_type']或data['access_token']可能为Null UserModel.fromJson(data['user'])解析时,UserModel中定义的非空String字段在接口返回的user数据中为Null
2. 修复Token拼接的空值问题
在authservice.dart中修改token赋值逻辑,增加空值兜底:
// 原代码 user.token = data['token_type'] + " " + data['access_token']; // 修改后 user.token = (data['token_type'] ?? '') + " " + (data['access_token'] ?? '');
3. 修复UserModel的JSON解析逻辑
检查UserModel的fromJson方法,确保所有非空字段都处理Null情况:
比如如果UserModel定义如下:
class UserModel { final String id; final String name; final String username; String? token; UserModel({required this.id, required this.name, required this.username, this.token}); factory UserModel.fromJson(Map<String, dynamic> json) { return UserModel( id: json['id'] ?? '', // 增加空值兜底 name: json['name'] ?? '', username: json['username'] ?? '', ); } }
如果接口返回的user字段可能为Null,必须用??运算符设置默认值,或者将字段改为可空类型(String?)。
4. 调试接口返回的完整数据
在authservice.dart中打印完整的响应体,确认返回的字段结构:
log('response body: ${response.body}');
通过日志确认data['token_type']、data['access_token']以及data['user']下的所有字段是否存在且不为Null。
5. 验证Provider逻辑
修复空值问题后,AuthService.register将正常返回UserModel,不会抛出异常,AuthProvider.register会返回true,触发Navigator.pushNamed(context, '/home')完成页面跳转。
内容的提问来源于stack exchange,提问作者leo
相关产品推荐
相关产品推荐

