0

I'm trying to fetch users within a 20 mile radius of a long and lat point. I've commented the problem in the code since it makes more sense pointing it out through there, the issue starts when defining the variable "usersQuery", and the issue is explained further in the userSnapshot.forEach function.

 export const fetchUsers = async (
  setUsers: Function,
  setLoading: Function,
  filters: Object,
  newFetch: boolean
) => {
  let userSnapshot;
  try {
    setLoading(true);
    const db = getFirestore();

    // Center of the search radius
    const center = new GeoPoint(37.783333, -122.416667);

    const radiusInMiles = 20;

    const usersCollection = collection(db, "users");

    // Query to fetch users within the search radius
    const usersQuery = query(
      usersCollection,
      where("coordinates", ">=", getMinGeopoint(center, radiusInMiles)),
      where("coordinates", "<=", getMaxGeopoint(center, radiusInMiles)),
      limit(30) //the issue lies here, because without the where "coordinates" queiries, the entire document is logged.
    );

    userSnapshot = await getDocs(usersQuery);

    // Fetch the users within the search radius
    userSnapshot.forEach((doc) => {
      console.log("userSnapshot: ", doc.id, doc.data()); //issue here, doc.data() only returns the "coordinates" field of the document, but fetches the entire document when this code is modified live, like right now when i finish writing this comment, the entire document data is logged
    });
  } catch (e) {
    console.log(e);
  } finally {
    setLoading(false);
  }

  // Helper function to calculate the minimum geopoint of the search area
  function getMinGeopoint(center: GeoPoint, radiusInMiles: number): GeoPoint {
    const earthRadiusInMiles = 3963.2;
    const distance = radiusInMiles / earthRadiusInMiles;
    const lat = center.latitude - distance;
    const lng =
      center.longitude - distance / Math.cos((center.latitude * Math.PI) / 180);
    return new GeoPoint(lat, lng);
  }

  // Helper function to calculate the maximum geopoint of the search area
  function getMaxGeopoint(center: GeoPoint, radiusInMiles: number): GeoPoint {
    const earthRadiusInMiles = 3963.2;
    const distance = radiusInMiles / earthRadiusInMiles;
    const lat = center.latitude + distance;
    const lng =
      center.longitude + distance / Math.cos((center.latitude * Math.PI) / 180);
    return new GeoPoint(lat, lng);
  }
};
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
David
  • 161
  • 1
  • 6
  • 1
    what does it mean if a lat/long is or isn't >= another lat/long? e.g is `(38,-123)` > `(37,-122)` ? perhaps you could use [geofirestore](https://geofirestore.com/) where distances between two geographic points are trivial – Jaromanda X Aug 05 '23 at 04:25
  • 1
    ^ it has *the added ability to say query near a center point, with a set radius in kilometers.* - all you'd need to know is how to convert your freedom units to metric – Jaromanda X Aug 05 '23 at 04:31
  • I tried following the geofirestore documentation exactly with just copy and paste and changed the "restaurants" collection to "users" and I get this error: [FirebaseError: Expected first argument to Firestore.collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore] I tried importing everything exactly the way they had it set as well. I can't really find an up to date resource on this :// – David Aug 05 '23 at 15:17

0 Answers0