Firebase Auth + Facebook Login（Swift3）

Firebase Auth+Facebook Loginでユーザ認証する。
公式ドキュメントでSwift3の情報がまだまだ少なく嵌ったため、備忘録の為の記事。

Firebaseのプロジェクト作成、FacebookのMy Apps作成は割愛します。
Githubへソースを上げているので、ご参考にしてください。
https://github.com/w2-yamaguchi/firebaseAuthTest

# 前提
## 環境
・Xcode8.3 + Swift3
・Firebase
・Facebook SDK

## Xcodeプロジェクトへ各SDKを導入
CocoaPodsでSDKを導入します。
導入されたSDKのバージョンは以下参照。

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

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

  # Pods for firebaseAuthTest
  pod 'Firebase/Core'
  pod 'Firebase/Auth'
  pod 'FacebookCore'
  pod 'FacebookLogin'
  pod 'FacebookShare'

  target 'firebaseAuthTestTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'firebaseAuthTestUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end
```
```
$ pod install
（抜粋）
Installing Bolts (1.8.4)
Installing FBSDKCoreKit (4.22.0)
Installing FBSDKLoginKit (4.22.0)
Installing FBSDKShareKit (4.22.0)
Installing FacebookCore (0.2.0)
Installing FacebookLogin (0.2.0)
Installing FacebookShare (0.2.0)
Installing Firebase (3.17.0)
Installing FirebaseAnalytics (3.9.0)
Installing FirebaseAuth (3.1.1)
Installing FirebaseCore (3.6.0)
Installing FirebaseInstanceID (1.0.10)
```
# ソース
https://github.com/w2-yamaguchi/firebaseAuthTest
## Info.plist
```xml:Info.plist
	<key>CFBundleURLTypes</key>
	<array>
		<dict>
			<key>CFBundleURLSchemes</key>
			<array>
				<string>********</string>
			</array>
		</dict>
	</array>
	<key>FacebookAppID</key>
	<string>********</string>
	<key>FacebookDisplayName</key>
	<string>firebaseAuthTest</string>
	<key>LSApplicationQueriesSchemes</key>
	<array>
		<string>fbapi</string>
		<string>fbauth2</string>
	</array>
```

##AppDelegate.swift
各SDKをインポート

```Swift:AppDelegate.swift
import Firebase
import FBSDKCoreKit
```

```Swift:AppDelegate.swift
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        // MARK: - Firebase
        FIRApp.configure()
        
        // MARK: - Facebook
        FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
        
        return true
    }
```
```Swift:AppDelegate.swift
    // MARK: - Facebook
    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        let handled:Bool = FBSDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)
        return handled
    }
```

## ViewController.swift
・ログイン画面のViewController
・サインイン処理（Facebook Login → Firebase Auth）

```Swift:ViewController.swift
    @IBAction func signInTapped(_ sender: Any) {
        
        let loginManager = LoginManager()
        loginManager.logIn([.publicProfile, .email], viewController: self, completion: {
            result in
            switch result {
            case let .success( permission, declinePemisson, token):
                print("token:\(token),\(permission),\(declinePemisson)")
                let credential = FIRFacebookAuthProvider.credential(withAccessToken: token.authenticationToken)
                self.signIn(credential: credential)
            case let .failed(error):
                print("error:\(error)")
            case .cancelled:
                print("cancelled")
            }
            
        })
    }
    
    func signIn(credential:FIRAuthCredential){
        FIRAuth.auth()?.signIn(with: credential) { (user, error) in
            if let error = error {
                print("error:\(error)")
                return
            } else {
                self.performSegue(withIdentifier: "SignedInSegue", sender: nil)
            }
            return
        }
    }
```

## MainViewCotroller.swift
・ログイン後画面のViewController
・サインアウト処理

```Swift:MainViewController.swift
    @IBAction func SignOutTapped(_ sender: Any) {
        let firebaseAuth = FIRAuth.auth()
        
        do {
            try firebaseAuth?.signOut()
            self.performSegue(withIdentifier: "signedOutSegue", sender: nil)
        } catch let signOutError as NSError {
            print ("Error signing out: %@", signOutError)
        }
    }
```