Flutter中Supabase嵌套过滤器实现报错:触发过滤器时出现NoSuchMethodError
问题分析与解决方案
错误根源
触发过滤器后报错,是因为Supabase返回了错误响应(Map类型),而非预期的结果列表(List类型)。核心问题有两个:
- subCategory的过滤逻辑完全错误,和category复用了同一个字段,导致查询逻辑冲突
- 未对查询返回结果的类型做校验,直接按List处理,当返回错误Map时就会触发
toList不存在的错误
具体修复步骤
- 修正subCategory过滤逻辑
当前代码中category和subCategory都用job_category_rel.category.id作为过滤字段,这不符合大类、小类的业务逻辑。假设subCategory对应sub_categories表,需要先在查询中关联该表,再调整过滤条件:
// 先修改select语句,加入sub_category的内连接 var query = Supabase.instance.client.from('jobs').select( '*,city:cities!inner(name_ar,name_en,id,country:countries!inner(id,name_ar,name_en)),job_category_rel:job_category_rel!inner(id, category!inner(id,name_ar,name_en), sub_category:sub_categories!inner(id,name_ar,name_en))'); // 然后修改subCategory的过滤条件 if (subCategory != 0) { query = query.eq("job_category_rel.sub_category.id", subCategory); }
如果你的subCategory字段逻辑不同,请根据实际表结构调整关联和过滤字段。
- 增加结果类型校验
在获取查询结果后,先判断是否为错误响应,避免后续操作报错:
final data = await query.order("created_at"); // 检查是否为错误响应(Supabase错误返回是Map格式) if (data is Map) { throw Exception(data['message'] ?? '查询数据失败'); }
- 处理空数据场景
当过滤后没有匹配记录时,data会是空List,直接访问data[0]会报错,需要先判断:
if (data.isNotEmpty) { var jsonString = jsonEncode(data[0]); debugPrint('DATA ARE : $jsonString', wrapWidth: 500); } else { debugPrint('未找到匹配的职位数据'); }
- 验证关联字段路径正确性
确认city.country.id是否和你的表结构匹配:
- 确保
cities表的外键字段(比如country_id)正确关联到countries表的id - 如果你的关联逻辑是直接在
cities表存储country_id,可以简化过滤条件为query.in_("city.country_id", countryList);,无需内连接countries表就能实现过滤,性能更优
修复后的完整代码
Future<List<Map<String, dynamic>>> fetchJobData( List<int> countryList, List<int> cityList, int category, int subCategory, ) async { try { var query = Supabase.instance.client.from('jobs').select( '*,city:cities!inner(name_ar,name_en,id,country:countries!inner(id,name_ar,name_en)),job_category_rel:job_category_rel!inner(id, category!inner(id,name_ar,name_en), sub_category:sub_categories!inner(id,name_ar,name_en))'); if (countryList.isNotEmpty) { query = query.in_("city.country.id", countryList); } if (cityList.isNotEmpty) { query = query.in_("city.id", cityList); } if (category != 0) { query = query.eq("job_category_rel.category.id", category); } if (subCategory != 0) { query = query.eq("job_category_rel.sub_category.id", subCategory); } final data = await query.order("created_at"); // 校验错误响应 if (data is Map) { throw Exception(data['message'] ?? '查询数据失败'); } // 处理空数据 if (data.isNotEmpty) { var jsonString = jsonEncode(data[0]); debugPrint('DATA ARE : $jsonString', wrapWidth: 500); } else { debugPrint('未找到匹配的职位数据'); } // 转换为指定类型返回 return data.cast<Map<String, dynamic>>(); } catch (e) { print("Error fetching data: $e"); throw e; } }
内容的提问来源于stack exchange,提问作者Ahmed Wagdi
相关产品推荐
相关产品推荐

