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

Flutter如何遍历Cloud Firestore集合计算用户距离并触发近距离通知

Cloud Firestore 附近用户距离判定功能实现方案

前提准备

  • 确保所有用户的Firestore文档中都存储了规范的经纬度字段,建议用官方GeoPoint类型存储,也可拆分存为latitude(纬度,取值范围-9090)、`longitude`(经度,取值范围-180180)两个数值字段
  • 提前向当前登录用户申请位置权限、通知权限,确保可以拿到用户实时定位、可以正常弹出通知提醒
  • 从Firebase Auth模块获取到当前登录用户的唯一标识,用于过滤掉用户自己的记录

步骤1:拉取目标用户数据

如果你的项目用户量较小(千级以内),可以直接拉取除当前用户外的全量用户数据,以下为Web端JS示例,其他端逻辑一致仅语法调整:

import { getFirestore, collection, getDocs, query, where } from "firebase/firestore";

const db = getFirestore();
// 当前登录用户的uid,从Firebase Auth模块获取
const currentUid = "当前登录用户的uid";
// 构造查询条件,过滤当前用户自身的记录
const userQuery = query(collection(db, "users"), where("uid", "!=", currentUid));
const querySnapshot = await getDocs(userQuery);

步骤2:实现经纬度距离计算

使用Haversine公式计算两个经纬度点的球面距离,米级精度完全满足200m的判定需求:

/**
 * 计算两个经纬度点之间的距离
 * @param {number} lat1 点1纬度
 * @param {number} lon1 点1经度
 * @param {number} lat2 点2纬度
 * @param {number} lon2 点2经度
 * @returns {number} 两点距离,单位为米
 */
function calculateDistance(lat1, lon1, lat2, lon2) {
  const earthRadius = 6371e3; // 地球平均半径,单位米
  const radLat1 = lat1 * Math.PI / 180;
  const radLat2 = lat2 * Math.PI / 180;
  const deltaLat = (lat2 - lat1) * Math.PI / 180;
  const deltaLon = (lon2 - lon1) * Math.PI / 180;

  const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
            Math.cos(radLat1) * Math.cos(radLat2) *
            Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

  return earthRadius * c;
}

步骤3:距离判定与通知触发

遍历拉取到的用户数据,逐个计算与当前用户的距离,符合条件则触发通知:

// 当前用户的实时经纬度,从设备定位模块获取
const currentLat = 39.9042;
const currentLon = 116.4074;
const nearUserList = [];

querySnapshot.forEach(doc => {
  const userData = doc.data();
  const distance = calculateDistance(
    currentLat, 
    currentLon, 
    userData.latitude, 
    userData.longitude
  );
  // 距离小于200米则加入附近用户列表
  if (distance < 200) {
    nearUserList.push(userData);
  }
});

// 存在附近用户时触发通知
if (nearUserList.length > 0) {
  // 可替换为对应端的推送通知接口,示例为Web端Notification API
  new Notification("附近用户提醒", {
    body: `当前有${nearUserList.length}位用户在你周边200米范围内`
  });
}

性能优化建议

如果你的项目用户量超过千级,全量拉取数据会产生大量不必要的性能损耗和计费开销,建议做以下优化:

  • 用GeoHash对经纬度进行编码后存储在Firestore中,查询时仅拉取当前用户所在GeoHash区块以及相邻8个区块的用户,大幅减少拉取的数据量
  • 配合Cloud Functions实现后端计算,仅将符合距离条件的用户数据返回给前端,减少前端计算压力

相关教程说明

社区和官方文档都有大量对应功能的实现演示,搜索Firestore地理位置范围查询、附近用户功能实现即可找到对应的文字和视频教程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 10:24:03