You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter结合Firebase开发时getExerciseByID方法返回null求助

问题根因

你遇到的返回null问题本质是forEach方法的返回值不会传递给外层的getExerciseByID函数:

  • 你在forEach的遍历回调里写的return exercise,只是结束当前这一次的遍历回调执行,不会终止整个遍历,更不会作为外层getExerciseByID方法的返回值返回
  • 你的getExerciseByID函数没有在forEach逻辑之外声明返回值,所以执行完遍历之后默认返回null

修复方案

方案1:替换forEach为普通for循环(最直观)

把你的getExerciseByID方法改成如下实现:

Exercise? getExerciseByID(String exerciseId) {
  for (var exercise in _exercises) {
    print('COMPARE1: ${exercise.id} AND $exerciseId');
    if (exercise.id == exerciseId) {
      print('COMPARE2: ${exercise.id} AND ${exerciseId}');
      return exercise;
    }
  }
  // 没有匹配到的情况可以根据业务逻辑调整,比如返回默认值/抛异常
  return null;
}

注意:如果存在匹配不到ID的情况,需要把方法返回值类型改为可空的Exercise?避免类型报错。

方案2:用内置的firstWhere方法简化代码

Dart的Iterable类型内置了匹配查找的方法,不需要自己写遍历逻辑,Dart 2.12+版本可直接用orElse参数处理无匹配的场景:

Exercise? getExerciseByID(String exerciseId) {
  return _exercises.firstWhere(
    (exercise) => exercise.id == exerciseId,
    orElse: () => null,
  );
}

额外优化建议

你当前在ListView的itemBuilder里直接调用getExerciseByID遍历列表,如果_exercises数量较多、列表项多的话会有重复遍历的性能损耗,可以提前把_exercises转成id为key的Map,后续查找直接达到O(1)时间复杂度:

// 初始化_exercises的时候同步生成缓存Map
Map<String, Exercise> _exerciseCache = {};
// 初始化时执行:
for (var e in _exercises) {
  _exerciseCache[e.id] = e;
}

// 后续查找直接调用即可,不需要遍历
Exercise? getExerciseByID(String exerciseId) => _exerciseCache[exerciseId];

内容的提问来源于stack exchange,提问作者Kitcc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 14:54:03