Search code examples
databaseswiftfirebaselocationcllocation

Recover data without treating the entire database - Google Firebase / Swift


I'm using the new Google Firebase database in my iOS (Swift) app.

When the user create an account, he is added to the database with some parameters like his name, his age, and mostly his current location (latitude / longitude).

I would like the app to find other users within XXkm around him.

I created the test users like this :

for index in 1...10 {

        let profile: NSMutableDictionary = [

            "username" : "User\(index)",

        ]

        let parameters = [ // IT IS PARIS LOCATION

            "latitude" : 48.856614,
            "longitude" : 2.352222

        ]

        self.ref.child("usersTest").child("userID:\(index)").child("profile").setValue(profile)
        self.ref.child("usersTest").child("userID:\(index)").child("parameters").setValue(parameters)

    }

This is how I proceed :

// MARK: GET RANDOM USER

    refHandle = ref.observeEventType(FIRDataEventType.Value, withBlock: { (snapshot) in


        // IN THE DATABASE, I MODIFY THE USER 1 TO BE MY OWN ACCOUNT,
        // SO I CHANGE THE LOCATION TO BE DIFFERENT FROM THE OTHER
        // USERS LOCATION

        let ownUserID = "userID:1"

        let usersDict = snapshot.value!["usersTest"] as! NSDictionary

        let ownLatitude = usersDict[ownUserID]!["parameters"]!!["latitude"] as! CLLocationDegrees
        let ownLongitude = usersDict[ownUserID]!["parameters"]!!["longitude"] as! CLLocationDegrees

        let ownMaxDistance = usersDict[ownUserID]!["parameters"]!!["max_distance"] as! CLLocationDegrees

        self.myLocation = CLLocation(latitude: ownLatitude, longitude: ownLongitude)


        let usersID = usersDict.allKeys as! [String]

        for index in 0...usersID.count - 1 {

            let foundUserID = usersID[index]

            if foundUserID != ownUserID {

                let users = usersDict[foundUserID] as! NSDictionary

                self.usersArray["user\(index)"] = users

                let userParameters = self.usersArray["user\(index)"]!["parameters"] as! NSDictionary

                let latitude = userParameters["latitude"] as! CLLocationDegrees
                let longitude = userParameters["longitude"] as! CLLocationDegrees

                let userLocation = CLLocation(latitude: latitude, longitude: longitude)

                let distance = self.getDistance(userLocation, city2: self.myLocation)

                if distance < ownMaxDistance {

                    print("The user is inside your radius")

                } else {

                    print("The user is outside your radius")

                }

            }

        }

    })


// MARK: GET DISTANCE - FUNCTION

    func getDistance(city1: CLLocation, city2: CLLocation) -> CLLocationDegrees {

        let distance: CLLocationDistance = (city1.distanceFromLocation(city2)) / 1000

        return distance

    }

The problem with this way is that all the database is loaded because the app load the database, and then it check if the found user is inside or outside your radius (ownMaxDistance).

I do not know how to classify found users in ascending order based on the distance between the found user and the user.

With 100/200 users in the database there is no problem, but if the database hold thousands of users, it will be very long to load all the users!

Thanks for your help !


UPDATE 1

To be clear, it is a Tinder like app


Solution

  • I found the solution ! I used the old version of Firebase (2.5.1) to install GeoFire, I didn't use Cocoapods, I installed all the frameworks manually with a bridging-header

    Link of the old Firebase : https://www.firebase.com/docs/ios/

    Ask me if you have troubles with the installation of the frameworks ;)