Can't connect to Firebase after connecting to Facebook - In Swift 3 - ios

Before moving to Swift 3 the user had to log in to the app by Facebook, and then it automatically logged in to your Firebase account. Everything was good, but then I moved to Swift 3. The log in button still exists, but after it asks for permission to log in to Facebook - nothing happens.
Here is my code before moving to Swift 3:
var loginButton: FBSDKLoginButton = FBSDKLoginButton()
override func viewDidLoad() {
super.viewDidLoad()
loginButton.hidden = true
FIRAuth.auth()?.addAuthStateDidChangeListener { auth, user in
if let user = user {
// User is signed in.
currentEmail = user.email!
print("DONE")
NSNotificationCenter.defaultCenter().postNotificationName("dontShowLogInView", object: nil)
} else {
// No user is signed in.
self.loginButton.center = self.view.center
self.loginButton.readPermissions = ["public_profile", "email", "user_friends"]
self.loginButton.delegate = self
self.view.addSubview(self.loginButton)
self.loginButton.hidden = false
}
}
// Optional: Place the button in the center of your view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
print("user logged in")
self.loginButton.hidden = true
activityIndicator.startAnimating()
if error != nil {
self.loginButton.hidden = false
activityIndicator.stopAnimating()
print("???")
//handle errors
} else if result.isCancelled {
self.loginButton.hidden = false
activityIndicator.stopAnimating()
let loginManager = FBSDKLoginManager()
loginManager.logOut()
//handle cancel
print("canceled")
} else {
let credential = FIRFacebookAuthProvider.credentialWithAccessToken(FBSDKAccessToken.currentAccessToken().tokenString)
FIRAuth.auth()?.signInWithCredential(credential) { (user, error) in
print("user logged to firebase app")
}
}
}
func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
print("user logged out")
}
And this is the code after moving to Swift 3:
var loginButton: FBSDKLoginButton = FBSDKLoginButton()
override func viewDidLoad() {
super.viewDidLoad()
//getFBUserData()
loginButton.isHidden = true
FIRAuth.auth()?.addStateDidChangeListener { auth, user in
if let user = user {
// User is signed in.
currentEmail = user.email!
print("DONE")
print(currentEmail)
NotificationCenter.default.post(name: Notification.Name(rawValue: "dontShowLogInView"), object: nil)
} else {
// No user is signed in.
self.loginButton.center = self.view.center
self.loginButton.readPermissions = ["public_profile", "email", "user_friends"]
self.loginButton.delegate = self
self.view.addSubview(self.loginButton)
self.loginButton.isHidden = false
}
}
// Optional: Place the button in the center of your view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: NSError!) {
print("user logged in")
self.loginButton.isHidden = true
activityIndicator.startAnimating()
if error != nil {
self.loginButton.isHidden = false
activityIndicator.stopAnimating()
print("???")
//handle errors
} else if result.isCancelled {
self.loginButton.isHidden = false
activityIndicator.stopAnimating()
let loginManager = FBSDKLoginManager()
loginManager.logOut()
//handle cancel
print("canceled")
} else {
let credential = FIRFacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
FIRAuth.auth()?.signIn(with: credential) { (user, error) in
print("user logged to firebase app")
}
}
}
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
print("user logged out")
}

Related

Firebase email verification always return false user not verified. iOS

I am implementing firebase email verification, but when user received an email it's redirecting to app which is fine. When I am trying to sign in with verified email Auth.auth().currentUser?.isEmailVerified always return false. Below is my code:
class ViewController: UIViewController {
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var signInBtn: UIButton!
var link: String!
override func viewDidLoad() {
super.viewDidLoad()
if let link = UserDefaults.standard.value(forKey: "Link") as? String{
self.link = link
signInBtn.isEnabled = true
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
#IBAction func didTapSignInWithEmailLink(_ sender: AnyObject) {
if let email = self.emailTextField.text {
Auth.auth().signIn(withEmail: email, link: self.link) { (user, error) in
if let error = error {
print("\(error.localizedDescription)")
return
}
}
} else {
print("Email can't be empty")
}
print(Auth.auth().currentUser?.email)
if Auth.auth().currentUser?.isEmailVerified == true {
print("User verified")
} else {
print("User not verified")
}
}
#IBAction func didTapSendSignInLink(_ sender: AnyObject) {
if let email = emailTextField.text {
let actionCodeSettings = ActionCodeSettings()
actionCodeSettings.url = URL(string: "https://example.firebaseapp.com")
// The sign-in operation has to always be completed in the app.
actionCodeSettings.handleCodeInApp = true
actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)
actionCodeSettings.setAndroidPackageName("com.example.android",
installIfNotAvailable: false, minimumVersion: "12")
Auth.auth().sendSignInLink(toEmail: email, actionCodeSettings: actionCodeSettings) { error in
if let error = error {
print("\(error.localizedDescription)")
return
}
print("Check your email for link")
}
} else {
print("Email cant be empty")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I've found the solution we need to reload the user, which will update the current user status. Call Auth.auth.currentUser.reload in didTapSignInWithEmailLink button func:
Auth.auth().currentUser?.reload(completion: { (error) in
if error == nil{
if let email = self.emailTextField.text {
Auth.auth().signIn(withEmail: email, link: self.link) { (user, error) in
if let error = error {
print("\(error.localizedDescription)")
return
}
}
} else {
print("Email can't be empty")
}
print(Auth.auth().currentUser?.email)
if Auth.auth().currentUser?.isEmailVerified == true {
print("User verified")
} else {
print("User not verified")
}
} else {
print(error?.localizedDescription)
}
})

sign in with facebook swift error

I am trying to do Sign In with Facebook/Firebase Swift authentication, and I'm at the point where there's a functioning button. I am trying to run something that performs a segue once the login is complete, but I have not been successful in my tries.
func viewDidLoad(){
let loginButton = LoginButton(readPermissions: [ .publicProfile, .email])
loginButton.center = view.center
view.addSubview(loginButton)
if let accessToken = AccessToken.current {
print("signed in")
}
}
func loginButtonDidLogOut(_ loginButton: LoginButton){
print("logged out of fb")
}
func loginButton(_ loginButton: LoginButton!, didCompleteWith result: LoginResult!, error: Error!) {
if error != nil {
print(error)
return
}

Facebook Login Error libc++abi.dylib: terminating with uncaught exception of type NSException

I am getting the following error while building the app. Anyway to fix this issue.
See the error details the end of application launch' *** and in the image.
class ViewController: UIViewController, FBSDKLoginButtonDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if(FBSDKAccessToken.current()==nil){
print("Not Logged In")
}
else{
print("Logged In..")
}
let loginButton = FBSDKLoginButton()
loginButton.delegate = self
loginButton.readPermissions = ["public_profile","email","users_friends"]
loginButton.center = self.view.center
self.view.addSubview(loginButton)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if(error == nil){
print("login complete")
}
else{
print(error.localizedDescription)
}
}
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
print("Logged out..")
}
}
enter image description here

Facebook Login with Firebase and LoginButton For IOS

I am trying to perform a FacebookLogin using Firebase and the Facebook Login button, but I keep getting this
error:Facebook login was cancelled.
2016-04-01 19:08:15.721
biblos[778:408049] Warning: Attempt to present
on
whose view is not in the
window hierarchy!
User logged out...
Facebook login was cancelled.
2016-04-01 19:08:53.675 biblos[778:408049] Warning: Attempt to present
on
whose view is not in the
window hierarchy!
My ViewController code is as follows:
import UIKit
import Firebase
import FBSDKCoreKit
import FBSDKLoginKit
class ViewController: UIViewController, FBSDKLoginButtonDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var loginButton = FBSDKLoginButton()
loginButton.readPermissions = ["public_profile", "email", "user_friends"]
loginButton.center = self.view.center
loginButton.delegate = self
self.view.addSubview(loginButton)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Facebook Login
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!)
{
let ref = Firebase(url: "https://biblos-thebookapp.firebaseio.com")
let facebookLogin = FBSDKLoginManager()
facebookLogin.logInWithReadPermissions(["email"], handler: {
(facebookResult, facebookError) -> Void in
if facebookError != nil {
print("Facebook login failed. Error \(facebookError)")
} else if facebookResult.isCancelled {
print("Facebook login was cancelled.")
} else {
let accessToken = FBSDKAccessToken.currentAccessToken().tokenString
ref.authWithOAuthProvider("facebook", token: accessToken,
withCompletionBlock: { error, authData in
if error != nil {
print("Login failed. \(error)")
} else {
print("Logged in! \(authData)")
}
})
}
})
}
func loginButtonDidLogOut(loginButton: FBSDKLoginButton!)
{
print("User logged out...")
}
}
This method is deprecated. Try to use logInWithReadPermissions:fromViewController:handler: instead and pass your UIViewController or nil (topmost will be used).
https://developers.facebook.com/docs/reference/ios/current/class/FBSDKLoginManager/

Facebook Login without FBSDKLoginButton in Swift

I am trying to add facebook login for my app. I am using the FBSDKLoginButton which comes with its own button and once you login it turns to logout. I don't want all that. I just need to add my own button a view. And in that button's #IBAction I want the facebook login to take place. The code which I am now using is
class ViewController: UIViewController,FBSDKLoginButtonDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if (FBSDKAccessToken.currentAccessToken() != nil)
{
// User is already logged in, do work such as go to next view controller.
}
else
{
let loginView : FBSDKLoginButton = FBSDKLoginButton()
self.view.addSubview(loginView)
loginView.center = self.view.center
loginView.readPermissions = ["public_profile", "email", "user_friends"]
loginView.delegate = self
}
}
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
println("User Logged In")
if ((error) != nil)
{
// Process error
}
else if result.isCancelled {
// Handle cancellations
}
else {
returnUserData()
// If you ask for multiple permissions at once, you
// should check if specific permissions missing
if result.grantedPermissions.contains("email")
{
// Do work
}
}
}
func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
println("User Logged Out")
}
func returnUserData()
{
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
println("Error: \(error)")
}
else
{
println("fetched user: \(result)")
let userName : NSString = result.valueForKey("name") as! NSString
println("User Name is: \(userName)")
let userEmail : NSString = result.valueForKey("email") as! NSString
println("User Email is: \(userEmail)")
}
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
How do I customise this and achieve what I need. Thanks in advance.
You might want to check the latest FacebookSDK, here's what i have:
#IBAction func connectWithFacebook(){
if FBSDKAccessToken.currentAccessToken() != nil {
FBSDKLoginManager().logOut()
return
}
let login:FBSDKLoginManager = FBSDKLoginManager()
login.logInWithReadPermissions(["email"], handler: { (result:FBSDKLoginManagerLoginResult!, error:NSError!) -> Void in
if(error != nil){
FBSDKLoginManager().logOut()
}else if(result.isCancelled){
FBSDKLoginManager().logOut()
}else{
//Handle login success
}
})
}
Otherwise with the older SDK you can do the following:
Add the FBSDKLoginButton to your view and set it invisible
Add your custom button
On your custom button IBAction perform a click on the FBSDKLoginButton with the method sendActionsForControlEvents
FBSDKLoginManager can be used if FB Login is handled via custom button.
For more info, your can check this.
Set current access is nil.
This calls [FBSDKAccessToken setCurrentAccessToken:nil] and
[FBSDKProfile setCurrentProfile:nil].
FBSDKAccessToken.setCurrentAccessToken(nil)
For Facebook logout.

Resources