Flutter Firebase中如何获取附近用户数据?(无需本地过滤)
解决方案:用Firestore原生地理查询实现附近用户数据获取
既然geoflutterfire已废弃且存在版本兼容问题,直接用Firestore官方提供的原生地理查询能力就能满足你的需求——所有过滤逻辑在服务端执行,客户端仅需发送当前位置即可拿到结果。
前置条件
你当前的markLocationAsSeen方法已经正确将用户位置以GeoPoint类型存储到Firestore,这一步无需修改。
步骤1:创建Firestore复合索引
Firestore的地理查询需要提前创建复合索引:
- 进入Firebase控制台的Firestore数据库页面
- 切换到「索引」标签,点击「创建索引」
- 选择目标集合(对应代码里的
missingPetsCollection/doc(id)/${FireStoreConstants.pathLocationMarkers}) - 添加字段:
location(类型选「地理点」),若需要按时间排序,再添加createdAt(类型选「升序」或「降序」) - 提交创建,等待索引生效(通常需要几分钟)
步骤2:编写附近用户数据查询代码
以下是查询当前位置附近用户标记的示例代码,可直接集成到你的项目中:
Future<List<DocumentSnapshot>> getNearbyMarkers(LatLng currentLocation, double radiusInKm) async { setIsLoading(true); try { // 将当前位置转为GeoPoint类型 final currentGeoPoint = GeoPoint(currentLocation.latitude, currentLocation.longitude); // Firestore地理查询默认单位为米,需转换公里为米 final radiusInMeters = radiusInKm * 1000; final querySnapshot = await missingPetsCollection .doc(id) // 确保此处id与markLocationAsSeen方法中的宠物ID一致 .collection(FireStoreConstants.pathLocationMarkers) // 预过滤缩小查询范围(可选,提升查询效率) .where('location', isLessThanOrEqualTo: GeoPoint(currentLocation.latitude + 0.01, currentLocation.longitude + 0.01)) .where('location', isGreaterThanOrEqualTo: GeoPoint(currentLocation.latitude - 0.01, currentLocation.longitude - 0.01)) // 服务端执行地理范围过滤 .where('location', isWithin: Circle(center: currentGeoPoint, radius: radiusInMeters)) // 可选:按创建时间倒序排列 .orderBy('createdAt', descending: true) .get(); setIsLoading(false); return querySnapshot.docs; } on Exception catch (e) { Logger().e(e); setIsLoading(false); return []; } }
关键说明
isWithin: Circle(...)是Firestore原生的地理范围查询,所有过滤逻辑在Firebase服务端完成,客户端仅需传入位置和半径参数- 预过滤的
isLessThanOrEqualTo/isGreaterThanOrEqualTo用于缩小查询的文档范围,可根据实际需求调整精度(比如0.01对应约1公里左右的地理范围) - 若不需要排序,可省略
orderBy,此时索引仅需包含location字段即可
内容的提问来源于stack exchange,提问作者Shakila
相关产品推荐
相关产品推荐

