Lasse Bickmann
Lasse Bickmann

Reputation: 205

Swift & Firebase - Observer returning nil after changing data

A have a problem in my app. When i initialize the app on the first ViewController i get some data from my Firebase server using this code and a object called "By" and an array of objects called "byer":

 func download() {
    byer.removeAll()
    self.Handle = self.ref?.child("Byer").observe(.childAdded, with: { (snapshot) in
        if let dictionary = snapshot.value as? [String: AnyObject] {
            let by = By()
            by.Latitude = dictionary["Latitude"]?.doubleValue
            by.Longitude = dictionary["Longitude"]?.doubleValue
            by.Name = snapshot.key
            let coordinate = CLLocation(latitude: by.Latitude!, longitude: by.Longitude!)
            let distanceInMeter = coordinate.distance(from: self.locationManager.location!)
            by.Distance = Int(distanceInMeter)
            byer.append(by)
            byer = byer.sorted(by: {$0.Distance! < $1.Distance! })
            DispatchQueue.main.async {
                selectedCity = byer[0].Name!
                self.performSegue(withIdentifier: "GoToMain", sender: nil)
            }
        }
    })
}

This all works fine. But the problem comes when i later in the app chance the value in the database. I use a button with this code:

 if byTextfield.text != "" && latitude != nil && longitude != nil {
        ref?.child("Byer").child(byTextfield.text!).child("Latitude").setValue(latitude)
        ref?.child("Byer").child(byTextfield.text!).child("Longitude").setValue(longitude)
    }

But for some reason the app crashes and a red line comes over the line:

 let coordinate = CLLocation(latitude: by.Latitude!, longitude: by.Longitude!)

From the download function in the top. And the text: "Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value.".

I have tried to remove the observer using:

 override func viewDidDisappear(_ animated: Bool) {
    self.ref?.removeObserver(withHandle: self.Handle)
}

But this dosn't seems to help. Any suggestions?

Upvotes: 0

Views: 350

Answers (1)

Y_Y
Y_Y

Reputation: 341

using guard statement you can easily handle the nil value of the longitude and latitude. i.e

func download() {
byer.removeAll()
self.Handle = self.ref?.child("Byer").observe(.childAdded, with: { (snapshot) in
    if let dictionary = snapshot.value as? [String: AnyObject] {
        let by = By()
        guard let latitude = dictionary["Latitude"]?.doubleValue,let longitude = 
        dictionary["Longitude"]?.doubleValue else
        {
        return
        }

        by.Latitude = latitude
        by.Longitude = longitude
        by.Name = snapshot.key
        let coordinate = CLLocation(latitude: by.Latitude!, longitude: by.Longitude!)
        let distanceInMeter = coordinate.distance(from: self.locationManager.location!)
        by.Distance = Int(distanceInMeter)
        byer.append(by)
        byer = byer.sorted(by: {$0.Distance! < $1.Distance! })
        DispatchQueue.main.async {
            selectedCity = byer[0].Name!
            self.performSegue(withIdentifier: "GoToMain", sender: nil)
        }
    }
  })
}

and if you want to unregister the observer from the firebase database reference then remove the database handler at the end of the childadded block.

Upvotes: 0

Related Questions