firebase / geofire-js Goto Github PK
View Code? Open in Web Editor NEWGeoFire for JavaScript - Realtime location queries with Firebase
License: MIT License
GeoFire for JavaScript - Realtime location queries with Firebase
License: MIT License
Awesome library, looks great! I'm trying to use it instead of what I'm currently doing (run through a firebase array of clubs close to a user, calculate distances with the Haversine formula, and put clubs within a certian distance into an array, then ng-repeat through that array to show to the user).
So with GeoFire I got the query working, and I can get the unique IDs of each club within the radius logged to the console. But how can I ng-repeat or show that to the user?
Right now my geofire and club data looks like:
"geoFire": {
"uniqueClubID": {
"g": "data",
"i": "data"
}
}
"clubs": {
"uniqueClubID": {
"name": "club name here",
"description": "This club does stuff"
}
}
Any help would be greatly appreciated, thanks!
Oh, and I'm not trying to show a map, I'm just trying to show a list of the club names and descriptions to the user.
Hi there,
Is it possible to retrieve a country information of a visitor without (the browser) asking the visitor to share their location with geofire?
Like, say, using visitor's IP to determine their location?
cheers
Is there a way to query once for a given location and radius? I don't want to get changes realtime in this use-case. Instead, I just need all the results once the query completes.
I'm looking for something similar to the once
function in Firebase.
Got the following error on Ubuntu Chrome:
"Uncaught Error: Attempted to find predecessor key for a nonexistent key. What gives? " in firebase.js:1
Shows "buses currently in the circle" and their names, but doesn't put any pins on the map and nothing is clickable, though the map itself works properly.
What about support for polygon based geoQueries ? The current API seems to provide support only for circular geoQueries.
Hi,
What is the best possible accuracy? Can I get within 500m?
Cheers.
Since it's a real-time, so the performance of JS execution might be crucial at some point. There are obvious pieces of code that can be optimized by either using native methods or lodash library. For example:
Array.isArray()
vs bject.prototype.toString.call(location) !== "[object Array]"
(perf comparison)forEach
method of Object.keys() to loop thru the object because for..in is extremely slow.obj[key] = undefined
instead of delete key
in order not to trigger code deoptimization of JS engines.What will it take to approve support for the latest version of Firebase? Are there any changes in Firebase 2.1.x that would causes anything in GeoFire to break?
I'm trying to use GeoFire with CommonJS and Browerify by I get this error whenever I require geofire in a module. I found this issue thread (tildeio/rsvp.js#339) on GitHub for users of the library. Was wondering if the fix should be done from GeoFire codebase.
Thanks!
It would be nice if I could receive events telling me exactly who entered and left the search radius, rather than only an event telling me what the whole result set is.
Based on Docs:
'With the release of GeoFire 3.1.0, this library now uses the new query functionality found in Firebase 2.0.0.'
In particular I am interested in limitToLast
query found in Firebase with expected usage:
geoFireRef.limitToLast(2).on("key_entered", function(key, location, distance) { ...
But it throws an error TypeError: geoFireRef.limitToLast is not a function
Is it possible to use Firebase queries in GeoFire?
Hi,
As you ask about enhancements, I got another interesting use case.
In my app, I want to send Pushs notification to users in the x miles around.
So, I use a Geofire query with key_entered.
But, I would like the query stop, once all the current child have been entered (like a .once() in Firebase). If new users come in the query, I don't want to send them a notification.
I could use a Firebase .once event and compare distance, but if a query would exist for that, I think it should be better.
What do you think?
Cheers,
Clément
Warning: Command failed: lib/geoFire.js:485: ERROR - variables, functions, and arguments cannot be deleted in ES5 strict mode
delete uniquesObj;
Great library!
Design question...(may be just as much Firebase as GeoFire related)
Would you consider it feasible to add hundreds of thousands of small geo indices?
I have use case where I have a user generated item that needs to be tagged with geo locations. Sometimes it may be 5 sometimes 5000. There will be thousands of these user generated items per day and storing all their tags in a huge geoindex will require me to fetch way to may to the client only to filter most of them out.
Right now geofire enables me to find points within a certain radius.
I think a query like "find the 10 points that are cosest to me" could also be useful.
You could, for example, highlight the buses in various colors to show which ones just moved into or out of the radius. For instance: green for new, red for about to leave.
My Geofire query only returns something if the radius is set to a seemingly arbitrary 1197 or above. Any less and nothing will be returned. When the data is returned and I log the distances, they are all less than 1, so this doesn't make any sense to me.
Any ideas for why this is occurring?
Code:
var firebaseRef = new Firebase("<firebase url>");
var geoFire = new GeoFire(firebaseRef);
var geoQuery = geoFire.query({
center: [50.72, -1.88],
radius: 1197 // the minimum radius that will return
});
geoQuery.on("key_entered", function(key, location, distance){
console.log(key + ', ' + location + ', ' + distance);
});
Thanks!
Lawrence
It would be nice to be able to rename geoFire keys. Maybe something like GeoFire.rename("some key", "some new name key").then();
As of right now, you have to do GeoFire.remove("some key").then(function () { GeoFire.set("some new key").then() });
With a lot of other Firebase libraries, errors begin with the name of the library, such as "Firebase Simple Login: error message."
We should adopt this practice for GeoFire. It will probably be easiest to just make a utility method logError(message)
which appends to "GeoFire:"
to the error message
.
I am getting the following error:
Error: undefined is not an object (evaluating 'new RSVP.Promise')
Any idea why?
How can i find list of posts made close to me or by users who are closest to me, for instance?
Here is how i setup my database:
1- users
*id
*email
*password
*longitude
*latitude
2- posts:
id
title
body
longitude
lattitude
How does geofire come in and what exact query do i write?
I have tried to implement geofire twice, all ending in failure because i dont understand the concept beyond the example in the docs
This is related to pull request #15.
The geohash length stored in GeoFire is limited by the length of g_BOUNDING_BOX_SHORTEST_EDGE_BY_GEOHASH_LENGTH
, which is currently 7. For small queries (less than 0.6 km), we still can only use a geohash of length 7 which means we end up loading a lot of locations which could be well outside of our query. We should increase the length of g_BOUNDING_BOX_SHORTEST_EDGE_BY_GEOHASH_LENGTH
to 10, which should give us a precision of 1m and eliminate this unnecessary memory footprint.
Currently we thrown an asynchronous error because the write to Firebase fails. We should throw these synchronously so you don't have to handle them in the promise's catch()
method. Should also add some unit tests for this.
I have managed to insert multiple records with geo.insertByLocWithId for the same id
Then, upon calling geo.removeById() not all references were removed.
When I opened the sfVehicles index.html, then I switched to another tab in Chrome, after a while, i switched back to sfVehicles index.html opened before, I found many vehicle icons on the map were shaking from left to right or up and down. I think it is a bug.
If GeoFire is being run in node, firebase is not included.
This:
var Firebase = require("firebase");
should be added to the following:
// Include RSVP if this is being run in node
if (typeof module !== "undefined" && typeof process !== "undefined") {
var RSVP = require("rsvp");
}
I want to use Sourcegraph for geofire-js code search, browsing, and usage examples. Can an admin enable Sourcegraph for this repository? Just go to https://sourcegraph.com/github.com/firebase/geofire-js. (It should only take 30 seconds.)
Thank you!
Command run bower install --save-dev angularGeoFire
Extract from build
bower rsvp#~3.0.9 ENORESTARGET No tag found that was able to satisfy ~3.0.9
Additional error details:
Available versions: 3.0.8, 3.0.6, 3.0.5, 3.0.4, 3.0.1, 3.0.0, 2.0.4, 2.0.1, 1.2.0, 1.1.1, 1.1.0, 1.0.0
this is in the v2 branch
Is it possible to limit results for a specific query?
Similar to .limitToLast() in the Firebase API
The sample Firebase security rules allow for anyone to come in and wipe out your geofire index, with a call to fb.set(null).
I know individual requirements will vary, but it might be a good idea to point out the risk of deletion and offer an alternative, such as allowing anyone to write assuming they aren't deleting.
{
"rules": {
"<your-geofire-node>": {
// Allow anyone to read from this node
".read": true,
// Index each location's geohash for faster querying
".indexOn": ["g"],
// Schema validation
"$key": {
// Allow anyone to write to this node, assuming they respect the schema and they are not trying to delete
".write": "newData.exists()",
".validate": "newData.hasChildren(['g', 'l']) && newData.getPriority().length <= 22 && newData.getPriority().length > 0",
"g": {
".validate": "newData.val() == newData.parent().getPriority()"
},
"l": {
"0" : {
".validate": "newData.isNumber() && newData.val() >= -90 && newData.val() <= 90"
},
"1" : {
".validate": "newData.isNumber() && newData.val() >= -180 && newData.val() <= 180"
},
"$other": {
".validate": false
}
},
"$other": {
".validate": false
}
}
}
}
}
I would like to update a node with new object, but the current method to do that is only for update location attributes of point, can we do something to improve that ?
See here http://snipt.org/Ahhl6
when I call the following more than once (and after geo.offPointsNearId)
geo.onPointsNearId(id, distance, function(array) {
console.log(array);
});
the returned array contains multiple elements of the same objects
It would be nice to support the setting of a desired promise library, such as Bluebird, to override the default RSVP lib. eg: GeoFire.Promise = require('bluebird');
Hi,
As mentioned here, I think it should be great to easily multi update data paths and a geofire path at the same time. As the set of Geofire is pretty complex, it's hard to directly copy/paste the code to make it works.
Here the use case : (I use the same as the link above but add a path to know where a post is located). So the structure :
{
posts: {
post1: {
from : user1,
message: "Hi",
},
post2: {
from : user2,
message: "Hey",
}
},
posts-location: {
post1: {
g : 'xxxxxxxx',
l: {
0 : latitude,
1 : longitude
}
},
post2: {
g : 'xxxxxxxx',
l: {
0 : latitude,
1 : longitude
}
}
},
users: {
user1: {
posts: {
post1: true
}
},
user2: {
posts: {
post2: true
}
}
}
}
Now I can add a post at the same time at users and posts (with multi-path update). But I need to set the position after. In my use case, a post without a position is not valid data, it's for that the best should be to do the 3 updates at the same times (if one fails, all fail).
Deleting Geofire path is easy (using update(null)), we can multi-update for delete, but for set/update, I loop for a way to do that easily,
Cheers,
Clément
So, we have a mobile app which filters 1000's of realtime position of cars and shows user's cars within a 5 mile radius of their current location. Geofire works as expected. Each driver app updates the position of that vehicle to Geofire. Geofire on client filters 5 mile radius of current user location.
However, geofire seems to be downloading all 1000's of cars realtime position to client and then sorting it at client side. how can we avoid this?
Ideally we send lat, long and radius and all these queries should happen at firebase server and not at client. This is likely to load client side with a lot of incoming data.
Is there a better way to query and avoid all realtime position being streamed to client?
The build fails because of a bad peer dependency. Even after fixing that, the tests don't pass because Firebase is not compatible with the used PhantomJS version. It might be time to upgrade to Mocha and be done with all the PhantomJS stuff.
with geofire?
I mean existing objects. not a new/removed/moved one.
I'd imagine a common scenario would be GPS tracking users from their own devices, the client should optionally clean up behind itself when the user disconnects and the data isn't "real time" anymore.
I have the following structure:
I would like to update the location, while preserving the data
There is GeoFire.set(key, location)
https://github.com/firebase/geofire-js#geofiresetkey-location
But when I call it the data
would be lost.
I think I've found a workaround but it doesn't seem very intuitive to me:
firebaseRef.child('data').once('value', function(snap) {
var data = snap.val();
geofire.set(name, [lat, long]).then(function() {
firebaseRef.child('data').set(data);
}, function(error) {
console.log('Error: ' + error);
});
});
Seem like a lot of work. Is there a better way?
Video explanation: https://www.youtube.com/watch?v=i5u77q7l8dU
You data sets are updating niceely: https://publicdata-transit.firebaseio.com/sf-muni :)
Thanks!
So, weird question...
Is there a way to easily get some random location points around your location? I.E. you have userLocation, and you want to make a random location point within a one mile radius of that location. Would something like that be possible with geoFire?
My CPU is near 100% after running the demo for a few minutes.
Hi there, I think I've run into a bug when canceling a query from within the key_entered callback when the query already has locations tracked. I've included a JS fiddle below - it triggers the debugger right before the error. Just step out and you'll end up in geofire.on(), and on line 1110 (geofire.js) in the next iteration of the for loop, locationDict is undefined.
_locationsTracked is being reset on the query.cancel() call. I think a solution might just be to check that _locationsTracked[key] still exists before trying to see if _locationsTracked[key].isInQuery is true.
For some reason, it's not displaying an error in the console, but stepping through definitely shows there's an error.
EDIT: to clarify, it's actually throwing an error in an angular app I'm running with a local bower install of geofire. It's using the following dependencies:
geofire#3.2.3
#2.3.2
rsvp#3.1.0
if that helps...
Within _listenForNewGeohashes()
, we end up querying nine geohashes which encompass a GeoQuery
. In cases where the query's radius is just greater than one of the values in g_BOUNDING_BOX_SHORTEST_EDGE_BY_GEOHASH_LENGTH
, we end up loading a lot more data than we need to since most of the geohashes we are querying for are not even close to being in our query. We should use a smarter algorithm to compute a bounding box around a GeoQuery
. This will probably involve doing more than nine geohash queries on geohashes of varying lengths.
I am trying to use GeoFire, but even after reading all the examples here https://github.com/firebase/geofire-js/tree/master/examples I don't quite understand how it works.
with this snipped you can set a geo location for a single key:
geoFire.set("some_key", [37.785326, -122.405696]).then(function() {
console.log("Provided key has been added to GeoFire");
}, function(error) {
console.log("Error: " + error);
});
but how do I use geo locations for complex objects instead of simple string keys?
what if you have a restaurant with a name, average dish price and opening hours? do you need to store them in a second collection and somehow join them in your query?
I found this discussion #40 — it answers the question that you actually need to keep the geofire data in a seperate collection, but i am still wondering:
how do you make more complex queries such as "near my location, open now and $15 avg dish price" ? do you really need to load all ids of locations nearby and then send those ids back to the server in a second query to filter out the ones that match the complex query? how do you do that? is there any example?
thanks a lot for your help!
Hey!
I am wondering if there is any way to handle extra conditions within the geoQuery? For example, I would like the query to also account for other variable?
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.