Home > Back-end >  Query Geohashes in firestore in JavaScript modular syntax
Query Geohashes in firestore in JavaScript modular syntax

Time:11-29

While going through Firebase's documentation for geohashing, Im using modular SDK, and I tried converting the namespace code, but I was encountering a TypeError that q.get is not a function

// Find cities within Dkm of [lat, lng]
const center = [Number(lat), Number(lng)];
const radiusInM = dist * 1000;
// Each item in 'bounds' represents a startAt/endAt pair. We have to issue
// a separate query for each pair. There can be up to 9 pairs of bounds
// depending on overlap, but in most cases there are 4.
const bounds = geohashQueryBounds(center, radiusInM);
const promises = [];

for (const b of bounds) {
    const q = query(
    collection(db, USERS_COL),
    orderBy('geohash'),
    startAt(b[0]),
    endAt(b[1])
    );
    promises.push(q.get());
}

Documentation Link

Documentation code:

st radiusInM = 50 * 1000;

// Each item in 'bounds' represents a startAt/endAt pair. We have to issue
// a separate query for each pair. There can be up to 9 pairs of bounds
// depending on overlap, but in most cases there are 4.
const bounds = geofire.geohashQueryBounds(center, radiusInM);
const promises = [];
for (const b of bounds) {
  const q = db.collection('cities')
    .orderBy('geohash')
    .startAt(b[0])
    .endAt(b[1]);

  promises.push(q.get());
}

CodePudding user response:

I recommend keeping the Firebase documentation handy when doing a conversion like this, as it has code snippets for both the older syntax and the newer syntax side by side.

For example, the documentation on executing a query shows that the syntax in v9 is:

getDocs(q)

CodePudding user response:

Attaching the code, incase others fall into the issue too: I had to completely remove the get function, use getDoc(), save the snapshot of data, and then compare with the center, by for loop

// Find cities within dist km of [lat, lng]
  const center = [Number(lat), Number(lng)];
  const radiusInM = dist * 1000;
  // Each item in 'bounds' represents a startAt/endAt pair. We have to issue
  // a separate query for each pair. There can be up to 9 pairs of bounds
  // depending on overlap, but in most cases there are 4.
  const bounds = geohashQueryBounds(center, radiusInM);
  const promises = [];

  for (const b of bounds) {
    const q = query(
      collection(db, USERS_COL),
      orderBy('geohash'),
      startAt(b[0]),
      endAt(b[1])
    );
    const querySnapshot = await getDocs(q);
    querySnapshot.forEach((doc) => {
      // doc.data() is never undefined for query doc snapshots
      promises.push(doc.data());
    });
  }

  var finalResult = [];
  // Collect all the query results together into a single list
  await Promise.all(promises)
    .then((snapshots) => {
      const matchingDocs = [];

      for (const snap of snapshots) {
        // We have to filter out a few false positives due to GeoHash
        // accuracy, but most will match
        const lat = snap.lat;
        const lng = snap.lng;
        const distanceInKm = distanceBetween([lat, lng], center);
        const distanceInM = distanceInKm * 1000;
        if (distanceInM <= radiusInM) {
          matchingDocs.push(snap);
        }
      }
      console.log('val', matchingDocs);
      return matchingDocs;
    })
    .then((matchingDocs) => {
      finalResult = matchingDocs;
      // return matchingDocs;
    });
  return finalResult;
  • Related