In my Xcode Project I already have a sign in feature that uses a user's username and password they created. Now I want to integrate a Facebook login in the project, but I am not completely sure how to do this. When someone makes an account through they way I have it now, they make and save a username and a password which can then be used in with PFUser.logIn(withUsername: ..., password: ...)
for whenever they want to sign in again.
But with Facebook, I do not know what unique identifier I am suppose to save their account with. I know there is a Facebook id that I can extract, but how do I login the user in after I get this? Like I said before I currently use PFUser.logIn(withUsername: ..., password: ...)
to log the users' in then I just use PFUser.current()?.username
to get all data related to that user. I heard that I am suppose to use PFFacebookUtils.logInInBackground
for this, but I already tried implementing it but when I press the "Continue with Facebook button", the app crashes (I screenshot error and placed it at bottom). I have copied my code of what I have so far. How do I integrate a signup with Facebook feature that will allow me to save a users Facebook id and what method do I use to sign the user in (i.e. PFFacebookUtils.logInInBackground
)? Here's my code so far:
@IBOutlet var facebookSignUpButton: FBSDKLoginButton!
var fullnameFB = String()
var idFB = String()
var emailFB = String()
var isFBSignUp = Bool()
override func viewDidLoad() {
super.viewDidLoad()
signUpWithFacebook()
}
func signUpWithFacebook() {
facebookSignUpButton.readPermissions = ["email", "public_profile"]
facebookSignUpButton.delegate = self
self.view.addSubview(facebookSignUpButton)
}
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if error != nil { //if theres an error
print(error)
} else if result.isCancelled { // if user cancels the sign up request
print("user cancelled login")
} else {
PFFacebookUtils.logInInBackground(with: result!.token!) { (user, error) in
if error == nil {
if let user = user {
if user.isNew {
print("User signed up and logged in through Facebook!")
} else {
print("User logged in through Facebook!")
}
if result.grantedPermissions.contains("email") {
if let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "email, name"]) {
graphRequest.start(completionHandler: { (connection, result, error) in
if error != nil {
print(error?.localizedDescription ?? String())
} else {
if let userDetails = result as? [String: String]{
print(userDetails)
self.fullnameFB = userDetails["name"]!
self.idFB = userDetails["id"]!
self.emailFB = userDetails["email"]!
self.isFBSignUp = true
}
}
})
}
} else {
print("didnt get email")
self.createAlert(title: "Facebook Sign Up", message: "To signup with Facebook, we need your email address")
}
} else {
print("Error while trying to login using Facebook: \(error?.localizedDescription ?? "---")")
}
} else {
print(error?.localizedDescription ?? String())
}
}
}
}
Console output:
2017-08-12 14:14:33.223472-0700 Project[2423:1001235] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'You must initialize PFFacebookUtils with a call to +initializeFacebookWithApplicationLaunchOptions'
*** First throw call stack: (0x188042fe0 0x186aa4538 0x188042f28 0x100b8f934 0x100b90020 0x100b9032c 0x10019eee8 0x1001a0a64 0x100867598 0x10086e998 0x10086e4f0 0x100871a94 0x18b3610d4 0x101521a10 0x101526b78 0x187ff10c8 0x187feece4 0x187f1eda4 0x189989074 0x18e1dd364 0x1001ec288 0x186f2d59c) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
As stated in the docs, you need to initialize PFFacebookUtils
before using it, like so:
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
// CODE...
PFFacebookUtils.initializeFacebook(applicationLaunchOptions: launchOptions)
}
Important: Must be done after Parse setup (Parse.initialize...
).