使用go-router传递ID路由时出现类型不匹配错误求助
问题分析与解决方案
错误type 'Null' is not a subtype of type 'String'的核心原因是路由跳转时传递的id参数为null,或GoRouter解析参数时未能正确获取id,导致state.params["id"]!强制非空时抛出类型不匹配异常。热重载后正常是因为重载时参数已正确传递或初始化完成。
排查与修复步骤
1. 确认跳转时id的有效性
在跳转代码中添加日志校验,避免空值传入路由:
onTap: () { print("跳转的产品ID: $id"); // 打印确认id值 if (id != null && id.isNotEmpty) { context.push("/product/$id"); } else { // 提示用户无效的产品ID ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("无效的产品ID")), ); } },
2. 优化GoRouter路由参数处理
移除强制非空断言,增加参数校验逻辑,防止空值流入页面:
GoRoute( path: '/product/:id', builder: (BuildContext context, GoRouterState state) { final productId = state.params["id"]; // 若id为空,跳转至首页或错误页 if (productId == null || productId.isEmpty) { return const MainPage(); } return DetailsView(id: productId); }, ),
3. 修复DetailsView的异步数据加载
当前initState中异步方法未更新状态,且直接使用doc.get()易因字段不存在抛出异常,优化如下:
class _DetailsViewState extends State<DetailsView> { String? urlImage; String? description; int? price; String? title; // 修改为返回Future,配合FutureBuilder管理加载状态 Future<void> getProductInfo(String id) async { final doc = await FirebaseFirestore.instance .collection('products') .doc(id) .get(); setState(() { // 使用data()?[]避免字段不存在时的异常 urlImage = doc.data()?["urlImage"]; description = doc.data()?["description"]; price = doc.data()?["price"]; title = doc.data()?["title"]; }); } @override Widget build(BuildContext context) { return FutureBuilder( future: getProductInfo(widget.id), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 构建产品详情UI return Scaffold( appBar: AppBar(title: Text(title ?? "产品详情")), body: Column( children: [ if (urlImage != null) Image.network(urlImage!), Text(description ?? ""), Text("价格: $price"), ], ), ); }, ); } }
4. 额外注意事项
- 确保Firebase Firestore中的文档ID与传递的
id完全匹配,避免因ID错误导致文档不存在。 - 若
id来自异步加载的列表数据,需确保数据加载完成后再渲染跳转卡片,防止id未初始化就被调用。
内容的提问来源于stack exchange,提问作者Mohammed Malek
相关产品推荐
相关产品推荐

