Add Geo-search to your website/app in just 9 lines of code
Tags: webdev, javascript, firebase, tutorial
Published: 2023-04-16 05:46:13

Ever wanted to add advanced features like **geo-search** to your website or app, but the process felt too overwhelming?

![confused](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4fy7xip09et3m76y97is.gif)

Well, I will **let you in on a trade secret**! 🤫

It can be done with **JUST 9 LINES OF CODE** using **Firestore**! 🤯

Let's get started!

![lets-get-started](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwrhbwzmd5fmonnm6nfi.gif)

## Add Geo-hash to your data

Before you can use **geo-search**, you would need to add one additional field to your data called `geohash`.

To generate the `geohash`, you can use a library called [**geofire-common**](https://www.npmjs.com/package/geofire-common).

```bash
npm install geofire-common
```

The `geohashForLocation` function accepts the **latitude** and **longitude** as input and returns a `geohash` for the **location**.

```ts
await setDoc(doc(db, "cities", "LA"), {
  name: "Los Angeles",
  lat: 34.0,
  long: -118.2,

  // store geohash
  geohash: geofire.geohashForLocation([lat, lng]),
});
```

**NOTE**: The **geofire library** is available for **Swift**, **Kotlin**, and **Java** too, thus enabling you to use it in your **mobile apps** as well.

## Querying locations within a radius

After adding the `geohash` to your data, you can now start querying **locations** from the **database**.

```ts
const getCitiesWithinRadius = async (
  radiusInM: number,
  center: [number, number]
) => {
  const bounds = geofire.geohashQueryBounds(
    center,
    radiusInM
  );

  const promises = [];
  for (const bound of bounds) {
    const q = query(
      collection(db, "cities"),
      orderBy("geoHash"),
      startAt(bound[0]),
      endAt(bound[1])
    );
    promises.push(getDocs(q));
  }

  const snapShots = await Promise.all(promises);
  const cities = snapShots
    .flatMap((snapShot) => snapShot.docs)
    .map((doc) => doc.data());
  return cities;
};
```

The `getCitiesWithinRadius` will accept the **radius in meters** and the **coordinates** (**latitude** & **longitude**) as input & return all the cities within the specified radius.

**NOTE**: To keep the code **clean** & **easy to read**, the **9 lines** have been broken into several more lines, if **clean code** isn't your thing, you can even use a **one-liner**.

## Limitations

As **Firebase** docs put it:

> **Edge Cases** - this query method relies on estimating the distance between lines of longitude/latitude. The accuracy of this estimate decreases as points get closer to the North or South Pole which means Geohash queries have more false positives at extreme latitudes.

To remove the **false positives**, you can use the `distanceBetween` function from the `geofire-common` library to **filter out the cities** that are outside the radius, which would require **additional computation**.

```ts
const filteredCities = cities.filter((city) => {
  const distanceInM = geofire.distanceBetween(
    [city.lat, city.long],
    center
  );
  return distanceInM <= radiusInM;
});

return filteredCities;
```

## Wrapping up

**Congratulations!**

![congratulations](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ob9nt4ufk68z586kaash.gif)

Now **location-based search** is no longer **rocket science**, but just a few lines of code away! 🚀

**The world is your playground! 🎉**

Finding **personal finance** too intimidating? Checkout my **Instagram** to become a [**Dollar Ninja**](https://www.instagram.com/the.dollar.ninja/)

# Thanks for reading

Need a **Top Rated Front-End Development Freelancer** to chop away your development woes? Contact me on [Upwork](https://www.upwork.com/o/profiles/users/~01c12e516ee1d35044/)

Want to see what I am working on? Check out my [Personal Website](https://tapajyoti-bose.vercel.app) and [GitHub](https://github.com/ruppysuppy)

Want to connect? Reach out to me on [LinkedIn](https://www.linkedin.com/in/tapajyoti-bose/)

Follow me on [Instagram](https://www.instagram.com/tapajyotib/) to check out what I am up to recently.

Follow my blogs for **bi-weekly new Tidbits** on [Dev](https://dev.to/ruppysuppy)

**FAQ**

These are a few commonly asked questions I get. So, I hope this **FAQ** section solves your issues.

1. **I am a beginner, how should I learn Front-End Web Dev?**
   Look into the following articles:

   1. [Front End Development Roadmap](https://dev.to/ruppysuppy/front-end-developer-roadmap-zero-to-hero-4pkf)
   2. [Front End Project Ideas](https://dev.to/ruppysuppy/5-projects-to-master-front-end-development-57p)

2. **Would you mentor me?**
   Sorry, I am already under a lot of workload and would not have the time to mentor anyone.