Firebase应用模拟器正常真机异常:Firestore连接错误求助
问题解决:Firestore真机连接失败(Okio版本冲突)
错误根源
你遇到的java.lang.NoSuchMethodError: No interface method getBuffer()Lokio/Buffer;是Okio版本冲突导致的:
- Firestore SDK依赖的Okio 2.x版本,和项目中其他依赖引入的Okio 3.x版本不兼容——Okio 3.x移除了
BufferedSource.getBuffer()方法,但Firestore底层通信代码仍在调用该方法,最终引发运行时错误。 - 模拟器因依赖缓存、环境差异未触发冲突,但真机环境会直接暴露问题。
解决步骤
1. 强制统一Okio版本
在Android项目的android/build.gradle文件中,添加版本强制规则,确保所有依赖使用与Firestore兼容的Okio 2.x版本(例如2.10.0):
allprojects { repositories { // 保留原有仓库配置 } configurations.all { resolutionStrategy { force 'com.squareup.okio:okio:2.10.0' force 'com.squareup.okio:okio-jvm:2.10.0' } } }
2. 清理缓存并重建项目
执行以下命令清除旧依赖缓存,避免残留冲突:
flutter clean flutter pub get cd android && ./gradlew clean cd .. flutter run
3. 排查冲突依赖(可选)
如果上述方法无效,用以下命令查看项目依赖树,定位引入高版本Okio的依赖,手动排除:
flutter pub deps
找到冲突依赖后,在pubspec.yaml中排除其Okio依赖,示例:
dependencies: some_conflicting_package: ^x.x.x exclude: - com.squareup.okio:okio
代码优化建议
除依赖问题外,组件代码存在几个潜在bug,建议优化:
1. 避免FutureBuilder重复发起请求
不要在build方法中直接调用getItems(),否则组件每次重建都会触发新请求。应在initState中初始化Future:
class _FoodListState extends State<FoodList> { late Future<List> _itemsFuture; @override void initState() { super.initState(); _itemsFuture = getItems(); // 仅初始化时调用一次 } // 保留原有getItems方法 @override Widget build(BuildContext context) { // ... 其他代码 FutureBuilder( future: _itemsFuture, // 使用预初始化的Future builder: (context, snapshot) { // ... } ) } }
2. 完善FutureBuilder状态处理
当前代码直接使用snapshot.data!,未处理加载中、请求失败的情况,易引发崩溃:
FutureBuilder( future: _itemsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } else if (snapshot.hasData && snapshot.data!.isNotEmpty) { // 保留原有列表渲染代码 return Padding( padding: EdgeInsets.symmetric(horizontal: 10.w), child: SizedBox( height: 748.h, child: ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (context, index){ return ListTile( // ... 原有ListTile代码 ); }, ), ), ); } else { return Center( child: Icon(Icons.close, size: 64.sp), ); } } )
3. 空安全处理
FirebaseAuth.instance.currentUser?.uid可能为空,需处理用户未登录场景:
Future<List> getItems() async{ final user = FirebaseAuth.instance.currentUser; if (user == null) { return []; // 用户未登录时返回空列表 } List x = []; final snapshot = await FirebaseFirestore.instance .collection("Users") .doc(user.uid) .collection("Items") .get(); for (var element in snapshot.docs) { x.add(element.data()); } return x; }
内容的提问来源于stack exchange,提问作者hellomenoob
相关产品推荐
相关产品推荐

