昨天我們已經完成了 Sign in with Facebook 的前置作業了,今天我們要來將功能實作出來
我們先在 Storyboard/Xib 上拉出一個 UIButton
在要實作 Sign in with Facebook 功能的 Controller 引入下面兩個
import FirebaseAuth
import FBSDKLoginKit
元件的 IBOutlet 如下
@IBOutlet weak var signInWithFacebookBtn: UIButton!
宣告一個 isSign 變數,型別為 Bool,用來判斷是否已經登入
然後在宣告一個 loginManager 常數,讓他等於 LoginManager(),用來進行登入/登出
var isSign: Bool = false // 預設為尚未登入
let loginManager = LoginManager()
接著在登入按鈕的 IBAction 加入下面的程式碼
@IBAction func signInWithFacebook(sender: UIButton) {
if (self.isSign) {
self.facebookAccountSignOut() // 已經登入的話,按下按鈕會執行登出功能
} else {
self.signInWithFacebook() // 尚未登入的話,按下按鈕會執行登入功能
}
}
按下按鈕登入成功後,Facebook 會回傳使用者的 accessToken
接著就可以用 FacebookAuthProivder.credential() 這個 method 來產生該使用者的憑證
後面就可以透過這個憑證來與 Firebase 串接在一起了
extension SignInWithFacebookVC {
// MARK: - Firebase Sign in with Facebook
// 登入帳號
func signInWithFacebook() {
loginManager.logIn(permissions: ["email"], from: self) { loginResult, error in
guard error == nil else {
CustomFunc.customAlert(title: "", message: "\(String(describing: error!.localizedDescription))", vc: self, actionHandler: nil)
return
}
guard ((loginResult?.isCancelled) != nil) else {
CustomFunc.customAlert(title: "Facebook 登入失敗!", message: "", vc: self, actionHandler: nil)
return
}
guard let accessToken = AccessToken.current else {
CustomFunc.customAlert(title: "無法取得 AccessToken!", message: "", vc: self, actionHandler: nil)
return
}
let credential = FacebookAuthProvider.credential(withAccessToken: accessToken.tokenString)
self.firebaseSignInWithFacebook(credential: credential)
}
}
func firebaseSignInWithFacebook(credential: AuthCredential) {
Auth.auth().signIn(with: credential) { authResult, error in
guard error == nil else {
CustomFunc.customAlert(title: "", message: "\(String(describing: error!.localizedDescription))", vc: self, actionHandler: nil)
return
}
CustomFunc.customAlert(title: "登入成功!", message: "", vc: self, actionHandler: self.getFirebaseUserInfo)
self.signInWithFacebookBtn.setTitle("Facebook Account Sign Out", for: .normal)
self.isSignIn = true
}
}
// 登出帳號
func facebookAccountSignOut() {
do {
try Auth.auth().signOut()
loginManager.logOut()
CustomFunc.customAlert(title: "帳號已登出!", message: "", vc: self, actionHandler: nil)
self.signInWithFacebookBtn.setTitle("Connect with Facebook", for: .normal)
self.isSignIn = false
} catch let error as NSError {
CustomFunc.customAlert(title: "", message: "\(String(describing: error.localizedDescription))", vc: self, actionHandler: nil)
}
}
}
如果要判斷目前是否已經有使用者登入了,可以在 viewWillAppear 加入判斷
// MARK: - 加入 Firebase 帳號狀態監聽
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let token = AccessToken.current, !token.isExpired {
CustomFunc.customAlert(title: "帳號已登入過!", message: "", vc: self, actionHandler: self.getFirebaseUserInfo)
self.signInWithFacebookBtn.setTitle("Sign Out", for: .normal)
self.isSignIn = true
} else {
// 目前尚無用戶登入
print("目前尚無用戶登入!")
}
}
要讀取目前登入使用者的資料,可以這樣來讀取
// MARK: - Firebase 取得登入使用者的資訊
func getFirebaseUserInfo() {
let currentUser = Auth.auth().currentUser
guard let user = currentUser else {
CustomFunc.customAlert(title: "使用者資訊", message: "無法取得使用者資料", vc: self, actionHandler: nil)
return
}
let uid = user.uid
let email = user.email
let name = user.displayName
CustomFunc.customAlert(title: "使用者資訊", message: "User Name:\(name!)\nUID:\(uid)\nEmail:\(email!)", vc: self, actionHandler: nil)
}
本篇的範例程式碼:Github