Flutter中如何实现Firestore查询距离当前位置500米范围内的用户
实现步骤
1. 引入依赖
需要用到geoflutterfire库处理地理位置查询,在pubspec.yaml中添加依赖:
dependencies: cloud_firestore: ^4.15.0 # 请使用对应最新稳定版 geolocator: ^11.0.0 geoflutterfire: ^3.0.3
2. 调整用户位置存储逻辑
仅存储GeoPoint类型的位置无法支持范围查询,需要额外存储geohash字段,存储代码如下:
import 'package:geoflutterfire/geoflutterfire.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; final Geoflutterfire geo = Geoflutterfire(); final FirebaseFirestore firestore = FirebaseFirestore.instance; // 存储用户位置时调用 GeoFirePoint userLocation = geo.point( latitude: position.latitude, longitude: position.longitude ); await firestore.collection('users').doc('当前用户ID').set({ 'location': userLocation.data, // 自动包含geohash、latitude、longitude三个属性 // 其他用户字段 }, SetOptions(merge: true));
3. 范围查询代码
直接调用封装好的范围查询方法即可拉取500米内的用户:
// 构造当前位置的中心点 GeoFirePoint center = geo.point( latitude: position.latitude, longitude: position.longitude ); // 构建查询 var userCollection = firestore.collection('users'); Stream<List<DocumentSnapshot>> nearbyUsersStream = geo.collection(collectionRef: userCollection) .within( center: center, radius: 0.5, // 单位为公里,500米对应0.5 field: 'location', // 和你存储位置的字段名保持一致 strictMode: true // 自动过滤geohash边界误差导致的超出范围的数据 ); // 监听流获取实时结果 nearbyUsersStream.listen((List<DocumentSnapshot> userList) { // userList即为500米范围内的所有用户文档数据 for (var userDoc in userList) { Map<String, dynamic> userData = userDoc.data() as Map<String, dynamic>; // 处理业务逻辑 } }); // 如果只需要单次查询,可调用 // List<DocumentSnapshot> userList = await nearbyUsersStream.first;
注意事项
- 首次运行如果触发索引缺失报错,按照错误提示里的指引跳转至Firebase控制台,点击自动创建索引即可
- strictMode开启后会自动做二次距离校验,排除geohash查询本身的边界误差,建议始终开启
- 如果你之前已经存量存储了GeoPoint类型的位置,需要给所有历史用户补写
location字段的geohash数据,才能正常查询到历史用户
内容的提问来源于stack exchange,提问作者Mozhgan Javadzadeh
相关产品推荐
相关产品推荐

