Flutter开发报错:Query<Object?>无法赋值给Query<Map<String,dynamic>>
开发Flutter交友应用(文件路径:d:/dating_app/lib/api/users_api.dart)时,使用cloud_firestore搭配geoflutterfire实现附近用户查询功能,VS Code在代码第36行.collection(collectionRef: usersQuery)的usersQuery参数位置标红,触发Dart静态分析错误:
- 错误码:
argument_type_not_assignable - 错误提示:
The argument type 'Query<Object?>' can't be assigned to the parameter type 'Query<Map<String, dynamic>>'
原有实现逻辑为:先声明Query类型的usersQuery变量,拼接用户状态、等级筛选条件后,经UserModel的filterUserGender方法追加性别筛选条件,最终传入geoflutterfire的collection方法时触发类型不匹配。
Dart中无泛型声明的Query类型会被默认推导为Query<Object?>,而geoflutterfire的collection方法要求collectionRef入参必须为Query<Map<String, dynamic>>类型,泛型参数不匹配导致静态分析报错。如果filterUserGender方法的入参、返回值也使用无泛型的Query类型,会进一步延续这个类型推导问题。
方案1(推荐,类型安全)
显式为Query指定正确的泛型参数,同步修改相关方法的类型声明:
- 修改
usersQuery的变量声明,指定泛型为Map<String, dynamic>:
/// Build Users query Query<Map<String, dynamic>> usersQuery = _firestore .collection(C_USERS) .where(USER_STATUS, isEqualTo: 'active') .where(USER_LEVEL, isEqualTo: 'user');
- 同步修改
UserModel中filterUserGender方法的签名,将入参、返回值的无泛型Query替换为带正确泛型的类型:
// 原方法签名如果是 Query filterUserGender(Query query),修改为: Query<Map<String, dynamic>> filterUserGender(Query<Map<String, dynamic>> query) { // 方法内部原有筛选逻辑不需要改动,仅修改类型声明即可 }
方案2(快速修复,适合临时验证)
如果暂时不想修改UserModel的方法签名,可以在传入参数时做显式类型强转:
final allUsers = await geo .collection(collectionRef: usersQuery as Query<Map<String, dynamic>>) .within( center: center, radius: settings![USER_MAX_DISTANCE].toDouble(), field: USER_GEO_POINT, strictMode: true) .first;
注意:强转方案需要保证Firestore对应集合的文档数据结构始终为
Map<String, dynamic>,否则运行时会抛出类型转换异常,生产环境优先使用方案1。
内容的提问来源于stack exchange,提问作者PusakaOfJava Sheor_ray

