Swift 程式語言

iOS開發者指南:如何使用Firebase整合Facebook登入

iOS開發者指南:如何使用Firebase整合Facebook登入
iOS開發者指南:如何使用Firebase整合Facebook登入
In: Swift 程式語言

不久前,James寫了一篇教程告訴讀者如何利用Firebase建立登入和註冊功能,現在開發人員常會使用一些聯邦式(Federated Identity)身份管理憑證,如Google登入和Facebook登入,讓用戶得以使用自己的Facebook帳戶註冊應用程序。這篇文章中,我們將學習如何使用Firebase身份驗證並且整合Facebook登入。

編者提醒:這是我們Intermediate iOS 10 Programming with Swift其中一個章節的簡化版本。現時只有英文版,中文版將於稍後推出。

在進入實作內文前,你可能有一個問題。為什麼我們需要Firebase身份驗證?為什麼不直接使用Facebook SDK來實現用戶身份驗證?

即使你要使用Firebase身份驗證,不代表你不需要Facebook SDK,你仍舊需要將它安裝在Xcode專案中。儘管如此,在實現Firebase身份驗證時,大多數時間都是使用你相當熟悉的Firebase SDK。這裡舉一個例子,這是用於在登入後檢索用戶顯示名稱的程式碼:

if let currentUser = FIRAuth.auth()?.currentUser {
    nameLabel.text = currentUser.displayName
}

如果你已經閱讀了前一章,應該會非常熟悉上面這段程式碼。現在讓我問你,如何檢索用戶的Facebook登入名稱?可能你會通過Facebook SDK文檔來尋找相應的API。

讓我告訴你,如果使用Firebase身份驗證,並且整合Facebook登入功能,可以使用相同的Firebase API(如上所示)從他/她的Facebook配置文件檢索用戶的名稱,聽起來不錯吧?

這是使用Firebase驗證與其他安全驗證服務配對的優點之一。而且,開發者可以在同一Firebase控制台中管理所有用戶(無論他們是使用電子郵件,Facebook還是Google登入)。

firebase-social-login-1

前情提要:請先參考這篇由Jame撰述的有關Firebase登入和註冊的文章,然後再學習本教程.

現在讓我們開始來看接下來的實作內容,實作可分為三個部分,以下是我們需要做的:
* 配置你的Facebook應用程式 – 要使用Facebook登入,需要在其開發者網站上創建一個新的應用程序,並完成一些配置,如應用程式ID和密碼。
* 在Firebase中設置Facebook登入 – 因為我們將使用Firebase進行Facebook登入,所以需要在Firebase控制台中設置你的應用程式。
* 將Firebase和Facebook SDK整合到Xcode項目中 – 完成所有配置後,最後一步是藉由Facebook和Firebase SDK透過程式碼實現Facebook登入。

它看起來很複雜,其實程式碼部分是相當簡單,僅然如此,它仍需要一些時間來做配置和專案設定。

Okay!讓我們開始吧。

The Demo Project

這個範例相當簡單,初始畫面有顯示兩個按鈕:使用Facebook *登入和使用Google*登入,我們將在本教程中實現Facebook登入按鈕,而Google登入按鈕讓讀者自行練習。

為了幫助讀者專注於學習Facebook登入,你可以下載初始項目,與本文內容一起進行練習。 當你下載初始項目,請打開FirebaseDemo.xcworkspace並將com.appcoda.FirebaseDemoLogin的bundle identifier更改為你自己的bundle identifier。這很重要,因為它必須是唯一的。

登入過程與電子郵件地址非常相似。當用戶第一次點擊Sign in with Facebook按鈕,應用程序為用戶打開登入畫面,登入畫面由Facebook提供,並且用戶需要使用他/她的Facebook帳戶登入。此外,用戶必須授予我們的應用程式權限,才能擷取他/她的電子郵件地址和公開個人資料(例如顯示名稱)。

firebase-demo-app

如果用戶有安裝Facebook,應用程序將切換到Facebook以授予權限。這是用戶首次使用Facebook登入應用程序的情況,Facebook通常會緩存用戶的login資訊,所以用戶下一次使用將會自動登入。

建立Firebase應用程式

要整合Facebook登入與Firebase,第一件事是創建一個Firebase應用程式,請先前往[https://firebase.google.com](https://firebase.google.com),然後進入到控制台。 接著,添加一個新項目並將其命名為任何您想要的名稱。

firebase-new-app

當Firebase替你創建了新項目後,它將帶你到Overview頁面,在此選擇iOS平台,然後按照畫面上的步驟填寫你的bundle ID,Firebase將生成一個名為GoogleService-Info.plist的文件。 下載它並將其添加到Xcode項目。

您可以跳過與Firebase SDK安裝相關的過程,因為初始專案已經將它包含進去了,只需跳到最後一步即可完成應用配置。

設置新的Facebook應用程式

如前所述,你將必須經歷幾個配置過程,下一步是設置一個新的Facebook應用程序。轉到[Facebook for Developers](https://developers.facebook.com/)網站,使用你的Facebook帳戶登錄。在我的應用程式的下拉式選單中,選擇[Add a new app]。系統會提示你為應用程式設定顯示名稱和類別。我把名字設置為NorthernLights,並選擇photo類別。

下一步,點擊Create App ID進入到下個步驟,接著將被帶到一個dashboard,你可以在此配置Facebook登入。

現在請選擇+Add Product,然後單擊Facebook Login旁邊的Get Started選項。選擇iOS後Facebook將指導開發者完成整合過程,你可以忽略Facebook SDK安裝的說明,我們將使用CocoaPods來安裝它。只需點擊繼續即可繼續執行下一步,同樣的我們也跳過第二步。在配置的第三個步驟中,你需要提供專案的bundle ID,將其設置為之前配置的bundle ID,然後單擊Save保存更改。

就這樣,你可以跳過剩餘的過程。如果你要驗證bundle ID設置工作,請點擊側邊菜單中的Settings,應該會看到一個iOS區塊顯示bundle ID的資訊。

在畫面設置中,應該會找到你的App ID密碼。在預設情況下,密碼*會被隱蔽起來,你可以單擊顯示按鈕來檢視它,我們需要這兩個訊息來進行Firebase配置。

在Firebase中配置Facebook Login

現在回到[Firebase控制台](https://console.firebase.google.com)並選擇你創建的應用程序(在這裡,我使用Northern Lights),在側邊menu中,選擇Authentication,然後選擇Sign-in Method

由於我們現在正在實現Facebook登入,請單擊Facebook並將開關翻轉到ON。你必須在這裡填寫兩個欄位:App IDApp密碼,這些是稍早在Facebook應用程式設定欄位中顯示的值,請相應地填入它們,並點擊Save保存更改。

你可能會注意到OAuth redirect URI,Google API使用OAuth 2.0協議進行身份驗證和授權。在用戶使用他/她的Facebook帳戶登錄並授予訪問權限後,Facebook將通過回調URL通知Firebase。在這裡,OAuth redirect URI是URL。

你必須複製這個URI並將其添加到你的Facebook應用程式配置中,現在回到你的Facebook應用程序。在Facebook登入側邊選單中,選擇Settings。請確保將之前複製的URI貼到Valid OAuth redirect URIs欄位中。點擊Save Changes保存設置。

很好!你已完成了Facebook應用程式和Firebase的配置。

設定專案內Firebase與Facebook的SDK

你將需要Firebase和Facebook的SDK,安裝這兩個SDK最簡單的方法是使用CocoaPods,要將SDK添加到項目,請按如下所示編輯Podfile:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'FirebaseDemo' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for FirebaseDemo
  pod 'Firebase/Core'
  pod 'Firebase/Auth'

  # Pods for Facebook
  pod 'Bolts'
  pod 'FBSDKCoreKit'
  pod 'FBSDKLoginKit'
end
注意:如果讀者正在使用初始專案,它已經與Firebase SDK一起安裝,所以Podfile附帶了Firebase的Core和Auth pod。

更改後,打開終端機並前往這個專案的文件夾,然後輸入以下命令安裝pod(請確保在執行命令之前關閉Xcode項目):

pod install

如果一切都很順利的進行,CocoaPods將會下載你指定的SDK,並且將它們安裝至Xcode的專案中。

firebase-social-login-10

配置Xcode專案

在我們深入Swift程式碼之前還有一個配置作業。請打開FirebaseDemo.xcworkspace。在專案導覽器(Project Navigator)中,右鍵單擊Info.plist文件,並選擇Open as *> *Source code。它將會以文本格式打開檔案,這實際上是一個XML文件。

</dict>標記之前插入以下XML程式碼片段:

CFBundleURLTypes

  
    CFBundleURLSchemes
    
      fb564148470450124
    
  

FacebookAppID
564148470450124
FacebookDisplayName
Northern Lights
LSApplicationQueriesSchemes

  fbapi
  fb-messenger-api
  fbauth2
  fbshareextension

上面程式碼是我自己的設定內容,你的應該會與我的不太一樣,請進行以下更改:

  • 將App ID(564148470450124)更改為你自己的ID,請在Facebook應用程式的Dashboard中找尋此ID。
  • fb564148470450124 更改為你自己的URL scheme. 將其替換為fb{你的App ID}
  • 將應用程式的顯示名稱(ex:Northern Lights)更改為你自己設定的名稱。

Facebook API將讀取Info.plist中的設定內容,藉此連接你的Facebook應用程式和管理Facebook登入,開發人員必須確保App ID與先前創建的ID相匹配。

LSApplicationQueriesSchemes用來指定應用程式中UIApplication類別的canOpenURL:方法得以使用的URL schemes。如果使用者安裝了官方Facebook應用程式,則可以切換到該應用程序以進行登入,在這種情況下,需要在這個key值中宣告所需的URL schemes,以便Facebook可以正確執行應用程序切換。

開始進入Swift程式碼之中吧!

最後,在完成所有繁瑣的配置後,是時候開始探討Swift程式碼的部分了。現在打開AppDelegate.swift並添加以下import語句:

import Firebase
import FBSDKCoreKit

application(_:didFinishLaunchingWithOptions:)函式中,請加入兩行程式碼來初始化Firebase並配置Facebook Login:

FIRApp.configure()
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)

在同一個class當中,請添加下面的函式:

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    let handled = FBSDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)
    
    return handled
}

上面的程式碼是用來做什麼的呢?FBSDKApplicationDelegate被設定用於顯示Facebook登入(例如切換到本地Facebook app)或Facebook對話框(類似於Facebook的web介面)的處理結果。為了在application(_:didFinishLaunchingWithOptions:)方法中正確使用Facebook SDK,需要調用application方法。

就像前面說的,Facebook登入過程可能會發生這些情況:

  • 使用者點擊Facebook登入按鈕。
  • 假設使用者安裝了本地的Facebook app,應用程序將切換到Facebook app,以請求用戶的權限。
  • 在獲得使用者的批准後,Facebook app將切換回我們的應用程式,並且傳遞用戶的憑證,接著繼續登入動作。

當從Facebook app切換回我們的應用程式時,將調用application(_:open:options:)方法,所以我們必須實現該方法來處理Facebook登入,為了正確處理登入動作,Facebook需要調用FBSDKApplicationDelegateapplication方法:

FBSDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)

現在打開WelcomeViewController.swift,這是歡迎頁面的view controller,用來顯示Facebook登入按鈕,在WelcomeViewController的class當中,首先添加幾個import語句以導入所需的SDK:

import FBSDKLoginKit
import Firebase

然後添加一個處理Facebook登入的操作方法:

@IBAction func facebookLogin(sender: UIButton) {
    let fbLoginManager = FBSDKLoginManager()
    fbLoginManager.logIn(withReadPermissions: ["public_profile", "email"], from: self) { (result, error) in
        if let error = error {
            print("Failed to login: \(error.localizedDescription)")
            return
        }
        
        guard let accessToken = FBSDKAccessToken.current() else {
            print("Failed to get access token")
            return
        }

        let credential = FIRFacebookAuthProvider.credential(withAccessToken: accessToken.tokenString)
        
        // Perform login by calling Firebase APIs
        FIRAuth.auth()?.signIn(with: credential, completion: { (user, error) in
            if let error = error {
                print("Login error: \(error.localizedDescription)")
                let alertController = UIAlertController(title: "Login Error", message: error.localizedDescription, preferredStyle: .alert)
                let okayAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
                alertController.addAction(okayAction)
                self.present(alertController, animated: true, completion: nil)
                
                return
            }
            
            // Present the main view
            if let viewController = self.storyboard?.instantiateViewController(withIdentifier: "MainView") {
                UIApplication.shared.keyWindow?.rootViewController = viewController
                self.dismiss(animated: true, completion: nil)
            }
            
        })

    }   
}

如果讀者已經閱讀了我們的[Firebase教程](https://www.appcoda.com.tw/firebase-login-signup/),除了與FBSDKLoginManager相關的程式碼,它非常類似於我們在實現電子郵件/密碼認證時使用的code,FBSDKLoginManager類別提供了記錄用戶進出的方法。在實作Login功能時,你可以調用logIn方法,並指定要請求的讀取權限。由於我們需要用戶的電子郵件地址和顯示名稱,因此將要求用戶授權public_profileemail的讀取權限。

在用戶登入Facebook後,無論他/她是否授予我們應用程式權限,都將會調用完整的處理程序。這裡我們先檢查是否有任何錯誤。如果沒有,我們繼續擷取用戶的access token,並通過調用將其轉換為Firebase憑證:

FIRFacebookAuthProvider.credential(withAccessToken: accessToken.tokenString)

其餘的程式碼你應該非常熟悉,我們使用Facebook憑證調用FIRAuthsignIn方法,如果發生任何錯誤,我們彈出一個錯誤對話框,否則,我們顯示主頁面並關閉當前視圖控制器(view controller)。

現在請切換到Main.storyboard,並選擇Welcome View Controller Scene,接著按住Control鍵,將Sign In With Facebook按鈕拖動到Dock的視圖控制器圖標,釋放按鍵並在彈出選單中選擇facebookLoginWithSender:連接操作方法。

firebase-demo-app-actionmethod

設定測試帳戶

現在到了測試這個應用程式的時候了,如果妳點擊Sign In with Facebook按鈕,應該要看到Facebook的登入畫面。但是你之前配置的Facebook應用程式仍處於開發模式,如果妳使用自己的Facebook帳戶登入應用程式,將會看到錯誤:

App Not Setup: This app is still in development mode, and you don't have access to it. Switch to a registered test user or ask an app admin for permissions.

現在,你有兩個選擇來測試這個應用程式:

  1. 將你的Facebook app切換到production模式 – 可以在開發人員信息中心將Facebook app從development模式更改為production模式。
  2. 為測試目的創建測試用戶(或多個測試帳戶) – Facebook允許開發人員創建一個測試帳戶,以便在Facebook app處於development模式時執行測試。

在應用程式處於開發階段,尤其是當涉及到身份驗證時,使用一般帳戶執行所有測試是一個不好的習慣。因此,我們將優先參考第二個選項。

現在回到Facebook開發人員信息中心(Facebook Developer dashboard)並選擇Northern Lights。在側邊選單中,選擇Roles > Test Users。

在這裡您可以點擊Add按鈕添加一個新的測試用戶。在彈出的選單中,將測試用戶數設置為1,然後點擊Create Test Users按鈕。 然後,Facebook將生成一個具有隨機名稱和電子郵件地址的測試用戶。點擊新測試用戶旁邊的Edit按鈕,然後選擇Change the name or password for this test user以修改其密碼。

測試Facebook Login

很好!你現在可以準備來測試這個app了,請運行這個應用程式,當它啟動後點選Sign In with Facebook,並且使用剛剛創建的測試帳戶登錄,如果一切順利,你應該能夠前進到主頁面。

firebase-demo-app

Facebook將會緩存你的登入狀態。因此,下次不再需要使用測試帳戶(或Facebook帳戶)去登入這個應用程式。

登出和使用者顯示名稱

如何登出和設定使用者檔案呢?我們需要從Facebook SDK使用指定的API嗎?你可以使用相同的程式碼片段(Code Snippet)從用戶的Facebook配置文件擷取顯示名稱。

if let currentUser = FIRAuth.auth()?.currentUser {
    nameLabel.text = currentUser.displayName
}

Firebase相當的聰明,它可以根據登入方法(無論是來自Facebook還是使用電子郵件/密碼)確定適當的顯示名稱。

對於登出作業,我們可以使用相同的API來實現使用者的登出動作。

FIRAuth.auth()?.signOut()

以上可以看到Firebase的威力。開發者只需要調用相同的API,而Firebase將會替你處理其餘繁重的工作。

總結

在本文中,我向讀者介紹如何使用Firebase去整合Facebook Login,這裡故意忽略Google登入的功能實作,請嘗試參考Google登入文件,看看你是否能替這個app完成Google登入啟用程序。

以供參考,你可以在GitHub下載完成專案

編者提醒:這是我們Intermediate iOS 10 Programming with Swift其中一個章節的簡化版本,如果你覺得這篇文章有用,應該會喜歡我們的書!現時只有英文版,中文版將於稍後推出。
譯者簡介:陳奕先-過去為平面財經記者,專跑產業新聞,2015年起跨進軟體開發世界,希望在不同領域中培養新的視野,於新創學校ALPHA Camp畢業後,積極投入iOS程式開發,目前任職於國內電商公司。聯絡方式:電郵[email protected]

FB : https://www.facebook.com/yishen.chen.54
Twitter : https://twitter.com/YeEeEsS

原文Using Firebase to Integrate Facebook Login in iOS Apps

作者
Simon Ng
軟體工程師,AppCoda 創辦人。著有《iOS 17 App 程式設計實戰心法》、《iOS 17 App程式設計進階攻略》以及《精通SwiftUI》。曾任職於HSBC, FedEx等跨國企業,專責軟體開發、系統設計。2012年創立AppCoda技術部落格,定期發表iOS程式教學文章。現時專注發展AppCoda業務,致力於iOS程式教學、產品設計及開發。你可以到推特與我聯絡。
評論
很好! 你已成功註冊。
歡迎回來! 你已成功登入。
你已成功訂閱 AppCoda 中文版 電子報。
你的連結已失效。
成功! 請檢查你的電子郵件以獲取用於登入的連結。
好! 你的付費資料已更新。
你的付費方式並未更新。