owned this note
owned this note
Published
Linked with GitHub
###### tags: `第13屆IT邦鐵人賽文章`
# 【在 iOS 開發路上的大小事-Day20】透過 Firebase 來管理使用者 (Sign in with Facebook 篇) Part2
昨天我們已經完成了 Sign in with Facebook 的前置作業了,今天我們要來將功能實作出來
# 畫面設計
我們先在 Storyboard/Xib 上拉出一個 UIButton
![](https://i.imgur.com/j1mbG2u.png)
# 程式實作
在要實作 Sign in with Facebook 功能的 Controller 引入下面兩個
```swift=
import FirebaseAuth
import FBSDKLoginKit
```
元件的 IBOutlet 如下
```swift=
@IBOutlet weak var signInWithFacebookBtn: UIButton!
```
宣告一個 isSign 變數,型別為 Bool,用來判斷是否已經登入
然後在宣告一個 loginManager 常數,讓他等於 LoginManager(),用來進行登入/登出
```swift=
var isSign: Bool = false // 預設為尚未登入
let loginManager = LoginManager()
```
接著在登入按鈕的 IBAction 加入下面的程式碼
```swift=
@IBAction func signInWithFacebook(sender: UIButton) {
if (self.isSign) {
self.facebookAccountSignOut() // 已經登入的話,按下按鈕會執行登出功能
} else {
self.signInWithFacebook() // 尚未登入的話,按下按鈕會執行登入功能
}
}
```
按下按鈕登入成功後,Facebook 會回傳使用者的 accessToken
接著就可以用 FacebookAuthProivder.credential() 這個 method 來產生該使用者的憑證
後面就可以透過這個憑證來與 Firebase 串接在一起了
```swift=
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 加入判斷
```swift=
// 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("目前尚無用戶登入!")
}
}
```
要讀取目前登入使用者的資料,可以這樣來讀取
```swift=
// 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)
}
```
# 成果
{%youtube DvKLIZOOQ-4 %}
本篇的範例程式碼:[Github](https://github.com/leoho0722/IT2021/blob/main/Day15~Day22%E3%80%81Day24~Day28/CocoaPodsDemo/CocoaPodsDemo/FirebaseVC/SignInWithFacebookVC/SignInWithFacebookVC.swift)