KotlinでFacebook連携しよう！

# 【Kotlin×mBaaS】シリーズ概要
* Kotlinで[ニフクラ mobile backend](http://mbaas.nifcloud.com/)(通称：mBaaS)を使ってKotlinで開発を始めたい人向けのドキュメントです。
* [ニフクラ mobile backendのAndroid(Java)用ドキュメント](http://mbaas.nifcloud.com/doc/current/index.html)を__Kotlin__用に書き換えて動かしてみたものをまとめました。
* 初心者でもわかりやすいよう心掛けて作っていますが、わかりにくい部分がありましたらコメントをいただければ訂正しますのでお気軽にご意見をお願いします。
* 今回は__＜SNS連携編＞__として_Facebook連携_です！

# 事前準備のお願い
* 事前にニフクラ [mobile backendの登録](http://mbaas.nifcloud.com/)とアプリの新規作成をし、 [KotlinでmBaaSを始めよう！](https://qiita.com/nifcloud_mb/items/5b6290977f3147c3bc4f)をご覧いただき、必要な初期設定(SDKのインストールなど)をAndroid Studio上で行った上でご利用ください。

# __KotlinでFacebook連携しよう！__
* 完成イメージはこんな感じ。「f Continue with Facebook」のボタンをタップするとfacebookログインのブラウザの画面に遷移します。
![FacebookLogin.png](https://qiita-image-store.s3.amazonaws.com/0/72656/5b387450-09f7-f62c-8581-9b0a4aebd2e2.png)

## 導入の流れ
1. Facebook SDKのインストール
1. Facebook for developers でアプリ登録をする
1. Facebook認証の実装
1. mBaaSダッシュボードでの設定
1. 実機でビルドする（動作確認）

* Facebook SDKのインストールの方法は、Android SDKのインストール方法同様「Mavenを利用する方法」と「frameworkを利用する方法」の２種類あります。Android SDKのインストールの仕方に応じて準備が必要です。
* 今回はより簡単な「__Mavenを利用する方法__」について解説します。

## Facebook SDKのインストール

プロジェクトでFacebook SDKを使用するには、ビルド依存性として追加し、インポートします。

* [Android Studio] > [New Project] > [Minimum SDK]に移動します。
* "API 15: Android 4.0.3" (またはそれ以降)を選択し、新しいプロジェクトを作成します。
* プロジェクトで、[your_app] > [Gradle Scripts] > [build.gradle (Project)]を開き、次のリポジトリが**buildscript { repositories {}}**に含まれていることを確認します。

```
repositories {
    jcenter()
}
```

* プロジェクトで、[your_app] > [Gradle Scripts] > [build.gradle (Module: app)]を開き、次のインプリメンテーションステートメントを**dependencies{}**セクションに追加して、最新バージョンのFacebookログインSDKをコンパイルします。

```
implementation 'com.facebook.android:facebook-login:[4,5)'
```
* プロジェクトを構築します。

## Facebook for developers でアプリ登録します。
* [Facebook for developers](https://developers.facebook.com/docs/facebook-login/android)を開きます。
* 「1. アプリを選択または作成」の「新しいアプリを作成」をクリックします。
![CreateAppId.png](https://qiita-image-store.s3.amazonaws.com/0/72656/887af19a-6f06-12ee-cb8d-12341f55371d.png)


* アプリダッシュボードにAndroidプラトフォームを追加します。

![AddFlatform.png](https://qiita-image-store.s3.amazonaws.com/0/72656/3aa6f2ba-df1c-c0b6-d320-31b44cc979bc.png)
![Screen Shot 2018-01-15 at 11.41.49 AM.png](https://qiita-image-store.s3.amazonaws.com/0/72656/b84f1fc4-1489-50e0-490d-84568cea9059.png)


## Facebook認証の実装
FacebookアプリIDと、Chromeカスタムタブの有効化に必要なIDの文字列を作成します。さらに、AndroidマニフェストにFacebookActivityを追加します。

* **/app/res/values/strings.xml**ファイルを開き、以下を追加します。

```xml
<string name="facebook_app_id">[APP_ID]</string>
<string name="fb_login_protocol_scheme">fb[APP_ID]</string>
```

* **/app/manifest/AndroidManifest.xml**ファイルを開き、以下のuses-permission要素を追加します。

```xml
<uses-permission android:name="android.permission.INTERNET"/>
```

* Facebook用アクティビティである以下のmeta-data要素を追加し、Chromeカスタムタブ用のアクティビティとインテントフィルターをapplication要素内に追加します。

```xml
<meta-data android:name="com.facebook.sdk.ApplicationId" 
        android:value="@string/facebook_app_id"/>
    
    <activity android:name="com.facebook.FacebookActivity"
        android:configChanges=
                "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
        android:label="@string/app_name" />
    <activity
        android:name="com.facebook.CustomTabActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="@string/fb_login_protocol_scheme" />
        </intent-filter>
    </activity>
```


### Facebookの認証情報でニフクラ mobile backendの会員登録を行う部分の処理
* Facebook SDKの**LoginButton**を追加すると、アプリに簡単にFacebookログインを追加できます。Facebookログインボタンを追加するには、レイアウトXMLファイルにボタンを追加します。

```xml
<com.facebook.login.widget.LoginButton
        android:id="@+id/login_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
```
<img width="1059" alt="FacebookLoginButton.png" src="https://qiita-image-store.s3.amazonaws.com/0/72656/401f6230-d28d-361e-314d-10a07834c651.png">

* Facebookログイン応答を処理するためにCallbackManager.Factory.createを呼び出すことでcallbackManagerを作成し、Facebookログインボタンにコールバックを登録します。
* Facebookログイン完了後にニフクラ mobile backendへのログインを実施するためにNCMBFacebookParametersで認証データを作成し、NCMBUserクラスのloginInBackgroundWithメソッドでログインします。

```kotlin:Kotlin
//Facebook
val callbackManager = CallbackManager.Factory.create()
```

```kotlin:Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    //********** SDKの初期化 **********
    NCMB.initialize(applicationContext, applicationKey, clientKey)
    /** ★ここに記述するとアプリ起動時に実行されます★ **/
    login_button.registerCallback(callbackManager, object: FacebookCallback<LoginResult> {
        override fun onSuccess(loginResult: LoginResult) {
            //認証用パラメータを作成
            val parameters = NCMBFacebookParameters(
                    loginResult.accessToken.userId,
                    loginResult.accessToken.token,
                    loginResult.accessToken.expires
            )

            //ニフクラ mobile backendにログイン
            NCMBUser.loginInBackgroundWith(parameters) { user, e ->
                if (e != null) {
                    // 新規登録失敗時の処理
                } else {
                    // 新規登録成功時の処理
                }
            }
        }

        override fun onCancel() {

        }
        override fun onError(error: FacebookException) {

        }
    })
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    callbackManager.onActivityResult(requestCode,
            resultCode, data)    
}
```
## ダッシュボードでの設定
[ニフクラ mobile backend](http://mbaas.nifcloud.com/)のダッシュボードで連携を許可する設定をします。

* 「アプリ設定」＞「SNS連携」を開いてFacebook連携のFacebook連携の許可にある「許可する」を選択します。
* 先ほどのFacebookのDashboard画面からApp IDをコピーして、FacebookAppIDに貼り付けます。
* 「保存する」をクリックします。
![SetFacebookId.png](https://qiita-image-store.s3.amazonaws.com/0/72656/460652a3-637f-e8a8-e7c4-37d36eeb2aff.png)


## ビルドする
* ビルドに成功したら、Facebookログインをおこなっていただき、[ニフクラ mobile backend](http://mbaas.nifcloud.com/)のダッシュボードを見てください。
* 会員管理の中にユーザー情報が登録され、`authData`にはアクセストークンが保存されているはずです。
![LinkedFacebook.png](https://qiita-image-store.s3.amazonaws.com/0/72656/f4e38f1d-12dc-8e9f-7106-599f8f6f8a0a.png)


* 取り出すとわかりますが、アクセストークンは結構長い…

```json:authData
{ "Facebook": { "id": "10***************", "access_token": "EAA****************************************", "expiration_date": { "__ type": "Date", "iso": "2018-03-16T07: 39: 37.765Z "}}}
```
※一部非表示（「`*`」に変更）にしています。

操作はここまでです。mBaaSを使ってのFacebookログインは、上手くできましたか？？

# 参考
* 【Kotlin×mBaaS】シリーズ
 * [KotlinでmBaaSを始めよう！](https://qiita.com/nifcloud_mb/items/5b6290977f3147c3bc4f)
 * [Kotlinでデータベースを使おう！①（保存・取得・更新・削除）](https://qiita.com/nifcloud_mb/items/eef8102fd47bf7e5aa9f)
 * [Kotlinでデータベースを使おう！②（関連付け・検索）](https://qiita.com/nifcloud_mb/items/36ddfce8294142c4d9d6)
 * [Kotlinでデータベースを使おう！③（ランキングを作る・アクセス権限）](https://qiita.com/nifcloud_mb/items/bf601f57eca8270416ae)
 * [Kotlinでログイン機能をつけてみよう！](https://qiita.com/nifcloud_mb/items/bcd4581dfade77cb123e)
 * [Kotlinでプッシュ通知を送ろう！](https://qiita.com/nifcloud_mb/items/e9f1b058798ad25db68b)