firebase / geofire-objc Goto Github PK
View Code? Open in Web Editor NEWGeoFire for Objective-C - Realtime location queries with Firebase
License: MIT License
GeoFire for Objective-C - Realtime location queries with Firebase
License: MIT License
Hi,
I have some doubts about the query queryAtLocation
In my example this is the query I use
gfCircleQuery = geoFire.queryAtLocation(center, withRadius:1.0)
My center point has this value
+48.85593490,+2.35885390
In meantime, I have a point (firebase) with the same location
Running the query it doesn't find the point.
But if I change the radius to 2.0 Kms.. The point is selected from my different events (.added, etc..)
Do I miss something?
I've added locations with identical lat/long coordinates to my database, but when I query I'm only getting the most recent one back. Is this the expected behavior?
I'm using GeoFire 2 and Firebase 3
I have updated my firebase framework version and everytime there is a GFEventTypeKeyEntered event the app crashes with this error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[FDataSnapshot name]: unrecognized selector sent to instance
I get the following error "No such module 'GeoFire'" when I try to use "import GeoFire" in swift. I have successfully installed GeoFire using the following:
pod 'Firebase'
pod 'Firebase/Database'
pod 'GeoFire', :git => 'https://github.com/firebase/geofire-objc.git'
There are no other issues in my code and it's fresh project. Has anyone else encountered or solved this issue?
Are you planning to publish GeoFire on http://cocoapods.org?
Due to the fact NSEnum isn't used the Event Type enums export to swift as:
public struct GFEventType : RawRepresentable, Equatable {
public init(_ rawValue: UInt32)
public init(rawValue: UInt32)
public var rawValue: UInt32
}
Inside a "manager" class, I'm creating two observers (one fore each .keyEntered and .keyExited) using a region query:
internal final class GeofireManager: NSObject {
internal var locationsRef: FIRDatabaseReference = FIRDatabase.database().reference(withPath: FirebaseRoutes.locations)
internal var geoFire: GeoFire!
weak var geofireDelegate: GeoFireRequestManagerDelegate!
var regionQuery: GFRegionQuery?
var regionKeyEntered: FirebaseHandle?
var regionKeyExited: FirebaseHandle?
// ...
internal func setGeofireObserver(withRegion region: MKCoordinateRegion) {
guard let gfd = self.geofireDelegate else { return }
regionQuery = geoFire.query(with: region)
regionKeyEntered = regionQuery!.observe(.keyEntered, with: { (key, location) in
guard let currentKey: String = key else { return }
let requestsRef: FIRDatabaseReference = FIRDatabase.database().reference(withPath: FirebaseRoutes.requests)
requestsRef.child(currentKey).observeSingleEvent(of: .value, with: { (snapshot) in
gfd.geofireAdded(snapshot: snapshot)
})
})
regionKeyExited = regionQuery!.observe(.keyExited, with: { (key, location) in
guard let currentKey: String = key else { return }
gfd.geofireRemoved(key: currentKey)
})
}
// ...
}
My delegate calls (gfd.geofireAdded(snapshot:)
and gfd.geofireRemove(key: currentKey)
) are working great... but during the lifecycle of my app from the viewController that is initializing this manager, I call the following function (and set the manager to nil) to remove the observers and deinit the manager class:
internal func removeGeofireObservers() {
if regionQuery != nil {
if regionKeyEntered != nil {
regionQuery?.removeObserver(withFirebaseHandle: regionKeyEntered!)
regionKeyEntered = nil }
if regionKeyExited != nil {
regionQuery?.removeObserver(withFirebaseHandle: regionKeyExited!)
regionKeyExited = nil }
regionQuery?.removeAllObservers()
regionQuery = nil
}
if circleQuery != nil {
circleQuery?.removeAllObservers()
circleQuery = nil
}
}
I've verified that the deinit {}
method is called on the manager object and I would expect that the observers and all their data would have gone away in this process... but shortly later when I reinitialize the manager object and setup the observers again, none of the .keyEntered
observers are fired UNLESS I move the map and update the region (at which point .keyExited
is fired on all the items that were there before) and then move back and update to the previous region (at which point .keyEntered
is fired again)...
Am I doing something wrong here? Why when I remove the observers and even deinit the parent class, does the data not totally refresh when I try it again at a later time?
Hello
Just letting you know that I have warning when using use_frameworks! option in cocoapod
Auto-Linking supplied '.../Pods/Firebase/Firebase.framework/Firebase', framework linker option at .../Pods/Firebase/Firebase.framework/Firebase is not a dylib
Hello! I want to update my existing GeoFire query criteria with different center location.
I documentation: "To update the query criteria you can use the center and radius properties on the GFQuery object. ". But there is no center and radius properties in GFQuery object (https://geofire-ios.firebaseapp.com/docs/Classes/GFQuery.html) ? How to solve this problem?
I am using GeoFire on my Xcode project to simply transfer longitude and latitude data from my project to the server. It is able to send info to the server from the simulator but not when I build on the iPhone. I'm not sure if this is due to GeoFire or my phone.
I am currently experiencing a deadlock using removeObserverWithFirebaseHandle
on @synchronize (self)
, any ideas what would cause this to happen ?
Hi there,
Since Firebase 2.4.0 release, installing GeoFire with cocoa pods (and use_frameworks!
) leads to:
[!] The 'Pods' target has transitive dependencies that include static binaries: (.../Firebase.framework)
Just updated my project to Swift 3, XCode 8, from Swift 2.2 and XCode 7 and started getting the above error on the following line:
regionQuery.observe(.keyEntered, with: { (key: String!, location: CLLocation!) in
...
}
Any clues what this is about?
Hey guys could you add a link for the latest version?
this link exists
https://github.com/firebase/geofire-objc/releases/download/v1.1.1/GeoFire.framework.zip
but not this one
https://github.com/firebase/geofire-objc/releases/download/v1.1.2/GeoFire.framework.zip
ld: '/App/Framework/GeoFire.framework/GeoFire(GFGeoHash.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Love to have a callback that contains the latest array of nearby nodes and is called the same time the Ready event is fired.
I'm having an issue where I have just begun implementing GeoFire and running a circle query and it seems to have caused a memory leak and blocked Firebase from popping any other events. The query takes upwards of 3 minutes to return with the single key that is the small, 300 meter circle. I have made a post on stack overflow about this as well that shows the very little amount of code I have so far added that seems to be causing the problems:
This bug is currently blocking me so any advice helping me figure out what the heck I am doing wrong (because i'm certain it must be me) would be amazing!
Thanks in advance!
Hi,
I'm just confused because the ReadMe says I can download the Geofire 2.0 Cocoapod, but when I try to do it, I get this message:
None of your spec sources contain a spec satisfying the dependency: GeoFire (~> 2.0)
.
And when I look at the page on the CocoaPod website, it says version 1.1.3 is the latest one.
Is this on purpose? When will the cocoapod be ready for this newest version of Geofire?
Thanks for geofire! It works like a charm!
I'm new to ios development and just figured out how to install framework and stuff. But I did not know how to create a bridging header file. I just downloaded and moved the GeoFire framework into my Swift xcode project, and I wrote "import GeoFire" in my .swift files and all the GeoFire functions work!
My question is, is this going to bite me in the butt later on by not creating a header file...? I tried to setLocation and getLocation functions and they all work perfectly onto my firebase database.
I'm making a global app that requires schools to be sorted from nearest to farthest, based on the user's location. To do this, I set geoFire.queryAtLocation(location, withRadius: 40075)
This causes a precision error ('Precision must be less than 23!'
) which I don't understand. So I reduced the radius to 4000. This time I'm getting a 'Not a valid geo location: [100.062421,-21.955856]'
error. I hard coded the user's location to be somewhere in Iceland CLLocation(latitude: 63.8875517, longitude: -21.9558564)
It seems that this error shows up when the radius hits one of the poles, in this case the north pole, since I don't get the same error when I change the user's location to somewhere nearer the equator.
Hi,
I'm doing some test with GFCircleQuery and the results are inside the circle but my app doesn't get keys ordered by distance. I don't understand this order filter.
Can someone explain me how it works?
Thank you.
I am trying to fetch location data within 25km radius and separate them for each km.
- 1km
- id1
- id2
- id3
- 2km
- id4
- id5
...
I tried using a for loop for index in 1...25
and fetch data for each radius, however it's re-fetching already fetched data. So this approach is not working either. This approach behaves like:
- 1km
- id1
- id2
- id3
- 2km
- id1
- id2
- id3
- id4
- id5
...
Is there a way to use geoFire.queryAtLocation(center, withRadius: 3.0 - 2.0)
like this? Or is it possible to achieve this using a for loop and a multidimensional dictionary (like below link)? What is the best way to achieve this?
I explained the problem in more detail here and here in more detail
Hi,
I setup my circle query like so
circleQuery = geoFire.queryAtLocation(currentLocation, withRadius: radius)
Then on a location listener I change the center:
circleQuery.center = currentLocation
And when the user changes the query radius:
circleQuery.radius = newRadius
My problem is that, I never get keyEntered or keyExited events when I change the radius.
If I kill the app and restart it, the keyEntered events get fired since the radius is stored in user defaults, so the next time circleQuery is created it gets the new value.
I declare these
let geoFire = GeoFire(firebaseRef: ref.child("locs"))
var circleQuery: GFCircleQuery!
I'm starting the circle query:
LocationManager.shared.observeLocations(.Block, frequency: .OneShot, onSuccess: { location in
currentLocation = location
if circleQuery != nil {
circleQuery.radius = radius
circleQuery.center = currentLocation
debugPrint("got ONESHOT location and UPDATING query objects")
} else {
debugPrint("got ONESHOT location and --CREATING-- query objects")
circleQuery = geoFire.queryAtLocation(currentLocation, withRadius: radius)
}
}) { error in
debugPrint(error.description)
}
And then I have these:
//remove post if far away from us
circleQuery.observeEventType(.KeyExited, withBlock: { (key: String!, location: CLLocation!) in
debugPrint("\(key) exited search area, remove from tableview")
stopMonitoringKey(key)
})
circleQuery.observeEventType(.KeyEntered, withBlock: { (key: String!, location: CLLocation!) in
print("------------> \(key) entered the search area and ")
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
monitorLostDataForKey(key) //start monitoring key values
})
Am I missing something?
This is in Xcode 7.3.1 with these versions for geofire/firebase:
Using Firebase (3.2.1)
Using FirebaseAnalytics (3.2.0)
Using FirebaseAuth (3.0.2)
Using FirebaseDatabase (3.0.1)
Using FirebaseInstanceID (1.0.6)
Using FirebaseStorage (1.0.1)
Using GeoFire (2.0.0)
Does someone have a good complete example how to use GeoFire with Swift3?
It's hard for me to find out how to use it... I think after searching a lot of newbies with firebase like I really want to have a good example how to populate a tableview with restaurants for example ordered by distance of the users location ?
Hi,
I'm trying to run the SFVehicles project inside the examples folder in a device. I'm using Xcode 7.3. When I build it, I get the error 'Firebase/Firebase.h' file not found.
I've been having trouble with the GeoFire pod in several Xcode 8/Swift 3 projects.
Building these projects often gets me an Apple Mach-O Linker error (Framework not found GoogleToolboxForMac), and in one particular project a "Lexical or Preprocessor Issue" ('FirebaseDatabase/FirebaseDatabase.h' file not found).
I've tried creating new projects from scratch with just the GeoFire pod, but the Linker error persists.
Not sure what I could be doing wrong...
I'm trying to use Geofire on Xcode 8.2/Swift 3.
I've imported the framework and added the bridging header.
Problem is, when I declare
var geoFire : GeoFire!
var geoFireRef : FIRDatabaseReference!
I get this error:
Command failed due to signal: Segmentation fault: 11
It would be incredible if there was a simple way to map from a geofire query result to a FirebaseDatabase query so that the FirebaseTableViewDataSource could populate. I think it would be great (because geofire writes to its own section of the database) if there was a way to make the object keys from a corresponding geofire query populate directly into a FIrebaseUI tableview through the FirebaseTableViewDataSource. I do not think this is already available because i have been working with this for a couple days and scouring the internet and have given up on a module that is already written, and I just wrote my own.
Am I missing something? is this a possibility in the future?
I'm not getting any results returned for a circle query and not sure what I'm doing wrong. Can anyone help? I'm receiving the "ready" block but not receiving any "keyEntered" data.
I need to get a list of all events, which have a location in the region. So this query should return one "event" = "mondayrun".
I'm using this code:
GeoFire *geoFire = [[GeoFire alloc] initWithFirebaseRef:[_ref child:@"events"]];
CLLocation *center = [[CLLocation alloc] initWithLatitude:37.7853889 longitude:-122.4056973];
GFCircleQuery *circleQuery = [geoFire queryAtLocation:center withRadius:20];
[circleQuery observeEventType:GFEventTypeKeyEntered withBlock:^(NSString *key, CLLocation *location) {
NSLog(@"Key '%@' entered the search area and is at location '%@'", key, location);
}];
[circleQuery observeReadyWithBlock:^{
NSLog(@"All initial data has been loaded and events have been fired!");
block(nil, nil);
}];`
And in my database I have an events collection, with a single object, located at those exact coordinates.
Any ideas what I'm doing wrong? Thank you!
I have been trying to use the query.observeReadyWithBlock callback without much success.
The callback fires before my data is loaded. Specifically I am loading the query results into an array. but when the callback fires the array is still empty, however after about a second it is populated.
I am using a large dataset, doing a lot of calculations prior to storing the data and also storing the information as large objects into the array (during the query.observeEventType loop). Could this be why?
query.observeReadyWithBlock({
println("All initial data has been loaded and events have been fired!")
})
Hi community,
I'm new to iOS development and I can't seem to get GeoFire working correctly. I read through the documentation but I can't seem to understand it correctly.
My app constantly monitors the user's location with CLLocation (I got that working correctly, the app is displaying the correct latitude and longitude information), and I have 2 locations in my database that is near the latitude/longitude. These two locations' latitude/longitude information is fed in from GeoFire setLocation() method and I can do that successfully too. My issue is I can't get queryAtLocation working correctly. I believe it has something to do with my data structure on Firebase, this is how it looks like (I faked the hash and latitude/longitude information here):
my_iOS_app:
post:
-K141KJSLF (first unique post IDs created by Firebase childByAutoID )
-coordinates
-g: "098salfj" (unique hash created by GeoFire)
-l
-0: 15.931309 (latitude populated by GeoFire)
-1: 100.131234 (longitude populated by GeoFire)
-K130AFE (first unique post IDs created by Firebase childByAutoID )
-coordinates
-g: "9had89j" (unique hash created by GeoFire)
-l
-0: 15.9413 (latitude populated by GeoFire)
-1: 100.14131 (longitude populated by GeoFire)
So the GeoFire reference is GeoFire(firebaseRef: my_iOS_app/post). When I do the queryAtLocation with center coordinates very close to those two posts' coordinates, the query_handle is not returning anything. Is it because my firebaseRef is pointing at "post"? Is it because the GeoFire hash/coordinate information is embedded two layers below the GeoFire firebaseRef?
In the GeoFire example with the bar reviews, I think they also embed their coordinates 1-2 layers below the Firebase reference too...Any know what I did wrong? Thank you in advance!
@mcdonamp I am trying to use both of this libs in RubyMotion app. But overtime I install the GeoFire pod it creates conflicts. The version of Firebase that GeoFire supports is lower than what Motion-firebase supports and its creating the double symbol
error. I don't want to nuke my dev machine for this. What can you do?
I have logged an issue on motion-firebase here rubymotion-community/motion-firebase#25
I have a geofire setup.
The Region enter event works fine.
how ever the Region exit never returns anything.
Maybe someone knows why????
`
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer)
{
print ("recieved update - key changed")
if (self.mapView.showsUserLocation && self.mapView.userLocation.location != nil)
{
let span = MKCoordinateSpanMake(0.0125, 0.0125)
let region = MKCoordinateRegion(center: self.mapView.userLocation.location!.coordinate, span: span)
self.mapView.setRegion(region, animated: true)
let location = mapView.userLocation.location
if regionQuery == nil {
let hostGeoFire = GeoFire(firebaseRef: self.ref.child("geo").child("hosts"))
regionQuery = hostGeoFire?.queryWithRegion(region)
regionQuery!.observeEventType(GFEventType.KeyEntered, withBlock: { (key: String!, location: CLLocation!) in
print("found a reqionKey: ",key)
})
{ (error) in
print(error.localizedDescription)
}
})
regionQuery!.observeEventType(GFEventType.KeyExited, withBlock: { (key: String!, location: CLLocation!) -> Void in
print ("I am leaving this host")
})
}
// // Query with an extremely limited span.
if foundQuery == nil
{
foundQuery = geofire?.queryAtLocation(self.mapView.userLocation.location, withRadius: 0.1)
foundQuery!.observeEventType(GFEventType.KeyEntered, withBlock: { (key: String!, location: CLLocation!) -> Void in
print ("THIS IS what i get", key)
})
foundQuery!.observeEventType(GFEventType.KeyExited, withBlock: { (key: String!, location: CLLocation!) -> Void in
print ("User Exit", key)
})
} else
{
foundQuery?.center = self.mapView.userLocation.location
}
}
}
`
Trying to compile the new framework version the following error appears:
`ld: framework not found Metal for architecture armv7``
Doing some research I think you should add the "-weak_framework Metal" linker flag when building the library.
Hi! First of all โ thanks for such awesome tool!
I'd like to ask for few things (or just for a reply if that's not possible).
Could we make this methods from GeoFire class public:
- (void)setLocationValue:(CLLocation *)location forKey:(NSString *)key withBlock:(GFCompletionBlock)block
-(NSDictionary *)jsonForLocation(CLLocation *)location
)And few words why do i need this:
In my case i need to import large amount of entries into firebase (~100k right now). Right now to save location in GeoFire-compatible way i need to make 1 additional request via GeoFire per saved object or replicate code from methods i listed above. I think it'll be better to make such changes, so i'd be able to prepare location value in json without making separate request.
Please let me know what do you think about this. If it's ok โ i'd be glad to make a PR with such changes.
Best, Ostap.
I tried my best to make sure this hasn't been posted before and couldn't find any record.
I think it would be nice if geofire would allow to save coordinates with keys that are generated by Firebase auto key generator so that one could associate locations with other information about the locations easily.
Currently I get an error saying that some characters are not allowed in keys for geofire when I try to use the same keys. I think it's because of the dash "-" in the Firebase keys.
Thanks for the good work guys!
Cheers
Hey guys, thanks for this cool lib
I noticed the following by using your module in my swift app
my current workaround is to remove and reassign my ready observer
Sorry, I am not super fluent with objc so its hard to investigate your code any further
geoFire.setLocation(CLLocation(latitude: 37.7853889, longitude: -122.4056973), forKey: "firebase-hq") { (error) in
if (error != nil) {
println("An error occured: \(error)")
} else {
println("Saved location successfully!")
}
}
The above code replaces all data inside the key "firebase-hq" with a "g" and "l" keys with data containing the geohash and the lat long. Shouldn't this just update the values and emulate Firebase's updateChildValues rather than replace all of them.
If not, is there a way to create a geoHash and update manually using Firebase's updateChildValues method from the GeoFire framework
I've tried everything
My Podfile:
`#Uncomment the next line to define a global platform for your project
platform :ios, '9.0'
target 'GeoFire' do
#Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
#Pods for GeoFire
pod 'Firebase/Core'
pod 'Firebase/Database'
pod 'GeoFire', :git => 'https://github.com/firebase/geofire-objc.git'
end`
Help me please !
Firebase 3.0 is now released and it requires GeoFire v1.2.
When will it be available?
Hi, sorry I dont know how to reopen a case, so I had to post a new one.
Here is how to recreate the bug.
Assuming you have Firebase set up already of course:
at least.. this is what happens here. I think it is a bug :(
ViewController.swift.zip
Undefined symbols for architecture arm64:
"OBJC_CLASS$_GeoFire", referenced from:
objc-class-ref in MapViewController.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
After Copied All Geofire Files to My Project and linked with bridgde-Header file this message keep coming when I try to run. Im updating my project from old firebase to new one with swift 3.0
When will be available the new version?
I'm creating a new swift project, and adding these dependancies in my PodFile:
pod 'Firebase', '> 2.2'> 1.1'
pod 'GeoFire', '
Then I'm including them both in a bridged header:
And the GeoFire.h header inside of the Pods project says it can't find the FireBase header:
Any help would be appreciated, thanks!
Does GeoFire work for sharing current locations of multiple users (who are constantly moving around), or is it only useful for stationary objects (like the bars in your example)?
I created a simple project with an MKMapView, a GeoFire query and an MKMapViewDelegate, which updates GeoFire query region every time UIMapView region changes. But that crash with an unhandled Not a valid geo location
exception, but only valid regions where used.
The problem is that queriesForRegion:region
is not wrapping locations when computing locations from regions. As a workaround I have to limit zoom on to MKMapView.
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.