2
votes

I want to store users under their Firebase generated uid. When I attempt to use this code:

  func showCredentials() {
        let credential = FacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
        Auth.auth().signInAndRetrieveData(with: credential) { (AuthDataResult, error) in
            if error != nil {
                print("Something went wrong with our Facebook User: ", error)
                return
            }
            print("Successfuly logged in with our Facebook User: ", AuthDataResult)
            self.performSegue(withIdentifier: "FacebookSegue", sender: self)
        }
        FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, email"]).start {
            (connection, graphResult, error) in
            if error != nil {
                print("Failed to Start Graph Request:", error)
                return
            }
            print(graphResult)
            let facebookDetail = graphResult as! NSDictionary
            let userID = facebookDetail["id"]
            let fullName = facebookDetail["name"]
            let email = facebookDetail["email"]
            let providerName = "Facebook"
            let userValues = (["Email": email, "Full Name": fullName, "UID": userID, "Provider":providerName])
            let databaseRef = Database.database().reference()
            let key = databaseRef.child("node").childByAutoId().key ?? ""
            let childUpdates = ["/Users/\(userID))/": userValues]
            databaseRef.updateChildValues(childUpdates)
            print(userID!)
            print(fullName!)
            let firebaseID = Auth.auth().currentUser?.uid
            print(firebaseID!)
        }
    }

The error I am given is: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value on the line where I am attempting to print the firebaseID. Why is the value of Auth.auth().currentUser?.uid nil and what can I do to obtain this value?

1
I had this issue before when attempting to retrieve a user's uid. Your's is not guaranteed to return the current user's information which is why the uid and likely the current user information is nil. You'll need to wait for the response to come back before you can retrieve the user's information. You might be able to init a global var uid and then assign it a value once the value has come back. Maybe this can help github.com/ThriveCommunityChurch/ThriveChurchOfficialApp/issues/…KSigWyatt

1 Answers

3
votes

You init 2 asynchronous requests at the same time

Auth.auth().signInAndRetrieveData and FBSDKGraphRequest(graphPath: "/me"

where the second may finish first causing the crash as the auth isn't yet finished , so you need to nest them to be sure that you access the user after the auth signin finishes

func showCredentials() {
    let credential = FacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
    Auth.auth().signInAndRetrieveData(with: credential) { (AuthDataResult, error) in
        if error != nil {
            print("Something went wrong with our Facebook User: ", error)
            return
        }
        FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, email"]).start {
        (connection, graphResult, error) in
        if error != nil {
            print("Failed to Start Graph Request:", error)
            return
        }
        print(graphResult)
        let facebookDetail = graphResult as! NSDictionary
        let userID = facebookDetail["id"]
        let fullName = facebookDetail["name"]
        let email = facebookDetail["email"]
        let providerName = "Facebook"
        let userValues = (["Email": email, "Full Name": fullName, "UID": userID, "Provider":providerName])
        let databaseRef = Database.database().reference()
        let key = databaseRef.child("node").childByAutoId().key ?? ""
        let childUpdates = ["/Users/\(userID))/": userValues]
        databaseRef.updateChildValues(childUpdates)
        print(userID!)
        print(fullName!)
        let firebaseID = Auth.auth().currentUser?.uid
        print(firebaseID!)

        DispatchQueue.main.async {
         print("Successfuly logged in with our Facebook User: ", AuthDataResult)
         self.performSegue(withIdentifier: "FacebookSegue", sender: self)
        }

    }


    }

}