firebase / geofire-js

GeoFire for JavaScript - Realtime location queries with Firebase
MIT License
1.44k stars 345 forks source link

Missing `once` or `get` and determination when search finished #257

Open step135 opened 1 year ago

step135 commented 1 year ago

You provide method on that tracks changes in real time, but I am interested to do search on static data once and determine when all children are added. In Realtime database it is done following way: .once('child_added', (v, nextKey) =>{ if (nextKey === null) allDataLoaded() }

thatfiredev commented 1 year ago

@step135 I couldn't understand your question. Is it related to geofire?

step135 commented 1 year ago

Why do you have so stupid question? Are you suffering from reading or intelligence disorder?

thatfiredev commented 1 year ago

Hey @step135

I'm sorry that you're having an issue searching data with geofire. We do our best to address everyone's feature requests, but first we need to understand your needs.

I can see you're frustrated, but I will need you to tone down so that we can have a clear and respectful communication and understand each other.

If I understand correctly, you'd like to have an API similar to child_added to run a search on geofire? Can you expand on your use case (what are you trying to achieve)?

samthecodingman commented 1 year ago

Hi @step135,

My understanding is that you want to do a one time poll of a GeoFire query and that the behaviour of such a feature would be similar to using getDoc(docRef) to get a Cloud Firestore Document just once instead of registering a real-time listener with onSnapshot(docRef, ...).

You can do so using the following custom method:

// Executes a GeoFire query and returns only the initial results as a Promise.
function queryOnce(geoFire: GeoFire, queryCriteria: QueryCriteria) {
  return new Promise(resolve => {
    const queryResults = [] as ({ key: string, location: Geopoint, distance: number })[]
          geoQuery = geoFire.query(queryCriteria);

    geoQuery.on("key_entered", (key, location, distance) => {
      queryResults.push({ key, location, distance });
    });

    geoQuery.on("ready", () => {
      geoQuery.cancel(); // unsubscribe all event listeners and destroy query
      // might want to sort queryResults here before resolving the promise
      resolve(queryResults);
    });
  });
}

Usage:

const points = await queryOnce(geoFire, {
  center: [10.38, 2.41],
  radius: 10.5
});
// points is an array of { key: string, location: Geopoint, distance: number } objects,
// in the order they were discovered by the query - not necessarily by distance.
// points may be an empty array if no results were found.

@thatfiredev If this were to be part of the library, you might define it as:

export interface GeoQueryResult {
  key: string;
  location: Geopoint;
  distanceFromCenter: number;
}

// an instance member of the GeoFire class
async function queryOnce(queryCriteria: QueryCriteria): Promise<GeoQueryResult[]>

Usage:

const results = geoFire.queryOnce({
  center: [10.38, 2.41],
  radius: 10.5
});