0

Whenever I run my app, it always crashes anywhere it states currentUserID. Not sure why. I printed the the currentUserID value and its nil. How can I correct it so it runs my app well. I can share the rest of the code if needed.

import UIKit
import MapKit
import CoreLocation
import Firebase
//import FirebaseDatabase

enum AnnotationType {
    case pickup
    case destination
    case driver
}

enum ButtonAction {
    case requestRide
    case getDirectionsToPassenger
    case getDirectionToDestination
    case startTrip
    case endTrip
}

class HomeVC: UIViewController, Alertable {

    @IBOutlet weak var mapView: MKMapView!
    @IBOutlet weak var centerMapBtn: UIButton!
    @IBOutlet weak var destinationTextField: UITextField!
    @IBOutlet weak var destinationCircle: UIView!
    @IBOutlet weak var cancelBtn: UIButton!
    @IBOutlet weak var actionBtn: UIButton!




    var delegate: CenterVCDelegate?

    var manager: CLLocationManager?

    let currentUserId = Auth.auth().currentUser?.uid
   // "IRD70YtgEyWRpaH8LkkjHZmjXPo1"


    var ref: DatabaseReference!

    var regionRadius: CLLocationDistance = 1000

    var tableView = UITableView()

    var matchingItems: [MKMapItem] = [MKMapItem]()

    var route: MKRoute!

    var selectedItemPlacemark: MKPlacemark? = nil

    var actionForButton: ButtonAction = .requestRide

    override func viewDidLoad() {
        super.viewDidLoad()



        ref = Database.database().reference()
       // print(ref.child("users").value(forKey: "users"))
        self.ref.child("userse").childByAutoId().setValue("wise")

        self.ref.child("users").child("sdsd").setValue("data")


//        print(Auth.auth().currentUser?.uid)
//        print(currentUserId)


        manager = CLLocationManager()
        manager?.delegate = self
        manager?.desiredAccuracy = kCLLocationAccuracyBest

        checkLocationAuthStatus()

        mapView.delegate = self
        destinationTextField.delegate = self

        centerMapOnUserLocation()

        DataService.instance.REF_DRIVERS.observe(.value, with: { (snapshot) in
            self.loadDriverAnnotationFromFB()



     DataService.instance.passengerIsOnTrip(passengerKey: self.currentUserId!, handler: { (isOnTrip, driverKey, tripKey) in
                    if isOnTrip == true {
                        self.zoom(toFitAnnotationsFromMapView: self.mapView, forActiveTripWithDriver: true, withKey: driverKey)
                    }
                })
            })

            cancelBtn.alpha = 0.0
            UpdateService.instance.observeTrips { (tripDict) in
                if let tripDict = tripDict {
                    let pickupCoordinateArray = tripDict["pickupCoordinate"] as! NSArray
                    let tripKey = tripDict["passengerKey"] as! String
                    let acceptanceStatus = tripDict["tripIsAccepted"] as! Bool

                    if acceptanceStatus == false {
                        //Broadcast to all driver
                        DataService.instance.driverIsAvailable(key: self.currentUserId!, handler: { (available) in
                            //check for errors
                            if let available = available {
                                if available == true {
                                    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
                                    let pickupVC = storyboard.instantiateViewController(withIdentifier: "PickupVC") as? PickupVC
                                    pickupVC?.initData(coordinate: CLLocationCoordinate2D(latitude: pickupCoordinateArray[0] as! CLLocationDegrees, longitude: pickupCoordinateArray[1] as! CLLocationDegrees), passengerKey: tripKey)
                                    self.present(pickupVC!, animated: true, completion: nil)
                                }
                            }

                        })
                    }
                }
            }

        }



        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            if self.currentUserId == nil {
                print("login")
            }
            DataService.instance.userIsDriver(userKey: self.currentUserId!, handler:  { (status) in
                if status == true {
                    self.buttonsForDriver(areHidden: true)
                }
            })

            DataService.instance.REF_TRIPS.observe(.childRemoved, with: { (removedTripSnapshot) in
                let removedTripDict = removedTripSnapshot.value as? [String: AnyObject]
                if removedTripDict?["driverKey"] != nil {
                    DataService.instance.REF_DRIVERS.child(removedTripDict?["driverKey"] as! String).updateChildValues(["driverIsOnTrip": false])
                }
                DataService.instance.userIsDriver(userKey: self.currentUserId!, handler: { (isDriver) in
                    if isDriver == true {
                        // Remove Overlays and annotation and hide request ride and cancel button
                        self.removeOverlaysAndAnnotations(forDrivers: false, forPassengers: true)
                    } else {
                        self.cancelBtn.fadeTo(alphaValue: 0.0, withDuration: 0.2)
                        self.destinationTextField.isUserInteractionEnabled = true
                        self.destinationTextField.text = ""

                        // Remove all map annotation and overlays
                        self.removeOverlaysAndAnnotations(forDrivers: false, forPassengers: true)
                        self.centerMapOnUserLocation()
                    }
                })
            })
DataService.instance.driverIsOnTrip(driverkey: self.currentUserId!, handler: { (isOnTrip, driverKey, tripKey) in
                    if isOnTrip == true {
DataService.instance.REF_TRIPS.observeSingleEvent(of: .value, with: { (tripSnapshot) in
                    if let tripSnapshot = tripSnapshot.children.allObjects as? [DataSnapshot] {
                        for trip in tripSnapshot {
                            if trip.childSnapshot(forPath: "driverKey").value as? String == self.currentUserId! {
                                let pickupCoordinateArray = trip.childSnapshot(forPath: "pickupCoordinate").value as! NSArray
                                let pickupCoordinate = CLLocationCoordinate2D(latitude: pickupCoordinateArray[0] as! CLLocationDegrees, longitude: pickupCoordinateArray[1] as! CLLocationDegrees)
                                let pickupPlacemark = MKPlacemark(coordinate: pickupCoordinate)
                                self.dropPinFor(placemark: pickupPlacemark)
                                self.searchMapKitForResultsWithPolyline(forOriginMapItem: nil, withDestinationMapItem: MKMapItem(placemark: pickupPlacemark))
                                self.setCustomRegion(forAnnotationType: .pickup, withCoordinate: pickupCoordinate)

                                self.actionForButton = .getDirectionsToPassenger
                                self.actionBtn.setTitle("GET DIRECTION", for: .normal)

                                // Fade in the action button
                                self.buttonsForDriver(areHidden: false)

                            }
                        }
                    }
                })
Rajesh Pandya
  • 1,540
  • 4
  • 18
  • 31
  • for all the forced(!) variables you have something is nil. Review DatabaseReference for example. – Alex Bailey Nov 23 '18 at 04:39
  • If you place a breakpoint at the start of viewDidLoad, what is the value of "currentUserId"? – David Rees Nov 23 '18 at 04:52
  • when you call auth may be chances HomeVC is called before authentication and you got currentUserId nil – Jatin Kathrotiya Nov 23 '18 at 04:57
  • Use Exception Breakpoint and you will come to which variable getting nil value – Manish Mahajan Nov 23 '18 at 05:30
  • Possible duplicate of [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?](https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – Tamás Sengel Nov 23 '18 at 22:41

1 Answers1

0

There are a few issues that should be addressed and then a core issue.

The first thing is that Auth.auth().currentUser? is an optional - meaning that it could have a value or could be nil. Doing this..

let currentUserId = Auth.auth().currentUser?.uid

is telling your code that no matter if its got a value or nil, attempt to assign the .uid to currentUserId.

Protect your code by safely unwrapping options

guard let currentUser = Auth.auth().currentUser else {return}
//now you can access currentUser as it won't be nil

or

if let currentUser = Auth.auth().currentUser {
   print("user is authenticated and currentUser is not nil")
} else {
   print("not authenticated")
}

Now the core of the issue is, as far as I can see, you're not authenticating the user at all and that needs to happen prior to accessing Auth.auth().currentUser

Here's a complete authentication function with error handling

func authUser(user: String, pw: String) {
    Auth.auth().signIn(withEmail: user, password: pw, completion: { (auth, error) in
        if let x = error {
            let err = x as NSError
            switch err.code {
            case AuthErrorCode.wrongPassword.rawValue:
                print("wrong password")
            case AuthErrorCode.invalidEmail.rawValue:
                print("invalued email")
            default:
                print("unknown error")
            }
        } else {
            if let user = auth?.user {  //note; safely unwrap optional
                print("uid: \(user.uid)")
            }
        }
    })
}
Jay
  • 34,438
  • 18
  • 52
  • 81