AndroidでFirebaseを用いたTwitterログイン

# はじめに
何か特別な背景があるわけではないですが、AndroidでTwitterログインをするサンプルアプリを作る機会があったので備忘録的にここに残しておきます。[→リポジトリ](https://github.com/Papillon6814/TwitterFirebaseAndroid)
AndroidでTwitterログインをするにはFirebaseを使うやり方と、Twitter4jをやり方の2つを見つけました。僕は個人的にFirebaseが好きなので前者のやり方で実装しました。

基本的に[Firebaseの公式の説明](https://firebase.google.com/docs/auth/android/twitter-login?hl=ja)に沿って進めていますが、Twitter APIの審査はすでに通っているものとします。Firebaseの設定でアクセストークンやAPIトークンなどを使用するので、それらも用意が必要です。


## 動作環境

M1 MacBook Pro
BigSur 11.3.1

# Androidプロジェクトの作成
Firebaseの設定をするよりも先にAndroidのプロジェクトを作成します。
今回は都合があり、KotlinではなくJavaで開発を行っています。

ここではプロジェクトを作成するだけなので細かい説明は省きますが、Android Studioで`Empty Project`を作成すればOKです。

次は早速Firebaseの準備に移ります。

# Firebaseの準備

## Firebaseとは
> Firebase は Google が提供しているモバイルおよび Web アプリケーションのバックエンドサービスです。

[参考](https://www.topgate.co.jp/firebase01-what-is-firebase)

バックエンドの開発に時間を割かなくても、Firebaseを使えば外部ログインやデータベースを利用することができます。
そして、Googleアカウントを持っていれば誰でもFirebaseを利用することができるのでFirebaseを利用するためにしなければならないことはとても少ないです。

## Firebaseのプロジェクト設定
### Firebaseのプロジェクトを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352824/adec37f0-126a-327c-1d5b-1c5bcb8a3218.png)
プロジェクト名やアカウント設定は自分の好みで大丈夫です。
Analyticsは使いませんが、有効にして進めました。

### Android用の設定を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352824/598e7ee3-44d0-2575-0355-87ccdf871191.png)
Firebaseコンソールのプラットフォーム選択エリアからAndroidのものを選択し、進めていきます。

**アプリの登録**
作成したAndroidプロジェクトのパッケージ名を入力します。(com.xxxxxx.xxxx)

**アプリのニックネーム**
ここは自分の好きなように付けます。

**デバッグ用の署名証明書**
AndroidのKeyStoreからSHA-1の文字列を取得し、ここに貼り付けます。
このとき、`~/.android`のディレクトリでコマンドを実行してください。

```
~/.android> keytool -list -v -keystore debug.keystore
```

このコマンドを入力するとパスワードが求められます。パスワードは`android`で通ると思います。
無事に出力がされたら、SHA-1のフィンガープリントが入手できると思うのでそれをFirebaseの方に貼り付けましょう。

### 設定ファイルのダウンロード
`google-services.json`をダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352824/4cf674f2-c7db-0345-a9cd-c0e740e7c4b1.png)
ここはやることがシンプルでわかりやすいですが、デバッグ用のフィンガープリントを追加していない状態で進めてしまうとこのjsonファイルの中身も証明書のことを反映しないまま生成されてしまうので、フィンガープリントを登録してから進みます。

### Firebase SDKの追加
Androidのプロジェクト内に記述を追加します。
ここは実際に表示されている通りに書いていくとわかりやすいです。
`google()`などの記述は最初から書いてあったりしたのでそこは追加で記述したりはしません。

以上で設定は完了です。

## FirebaseでのAuthentication設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352824/8a754467-b8da-0cfb-3560-50a211d00e4e.png)
Firebaseコンソールのメニューから`Authentication`を選択します。
`Sign-in method`のタブから`Twitter`を選択し、有効にします。このときTwitterのAPIキーとAPIシークレットキーが必要なのでTwitterのDeveloper Portalで取得しておきます。

キーを設定したら、FirebaseのコールバックURLをTwitter Developer Portal側にも登録します。

Authenticationの設定は以上です。

## AndroidへのTwitterログイン記述

### 依存関係の記述
まずはFirebase Authentication Androidライブラリの依存関係について記述します。

```gradle:app/build.gradle
dependencies {
    // Import the BoM for the Firebase platform
    implementation platform('com.google.firebase:firebase-bom:28.1.0')

    // Declare the dependency for the Firebase Authentication library
    // When using the BoM, you don't specify versions in Firebase library dependencies
    implementation 'com.google.firebase:firebase-auth'
}
```

### ログイン処理の記述
次にログイン処理について記述します。
今回作ったのは動作のサンプルなので、とりあえず動くようにMainActivityに記述しました。

```java:MainActivity
package com.example.fbapp;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.OAuthProvider;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onResume() {
        super.onResume();

        OAuthProvider.Builder provider = OAuthProvider.newBuilder("twitter.com");

        FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
        Task<AuthResult> pendingResultTask = firebaseAuth.getPendingAuthResult();
        if (pendingResultTask != null) {
            // There's something already here! Finish the sign-in for your user.
            pendingResultTask
                    .addOnSuccessListener(
                            new OnSuccessListener<AuthResult>() {
                                @Override
                                public void onSuccess(AuthResult authResult) {
                                    // User is signed in.
                                    // IdP data available in
                                    // authResult.getAdditionalUserInfo().getProfile().
                                    // The OAuth access token can also be retrieved:
                                    // authResult.getCredential().getAccessToken().
                                    // The OAuth secret can be retrieved by calling:
                                    // authResult.getCredential().getSecret().
                                }
                            })
                    .addOnFailureListener(
                            new OnFailureListener() {
                                @Override
                                public void onFailure(@NonNull Exception e) {
                                    // Handle failure.
                                }
                            });
        } else {
            // There's no pending result so you need to start the sign-in flow.
            // See below.

            firebaseAuth
                    .startActivityForSignInWithProvider(/* activity= */ this, provider.build())
                    .addOnSuccessListener(
                            new OnSuccessListener<AuthResult>() {
                                @Override
                                public void onSuccess(AuthResult authResult) {
                                    // User is signed in.
                                    // IdP data available in
                                    // authResult.getAdditionalUserInfo().getProfile().
                                    // The OAuth access token can also be retrieved:
                                    // authResult.getCredential().getAccessToken().
                                    // The OAuth secret can be retrieved by calling:
                                    // authResult.getCredential().getSecret().
                                    Context context = getApplicationContext();
                                    Toast.makeText(context , "ログインしました", Toast.LENGTH_LONG).show();
                                }
                            })
                    .addOnFailureListener(
                            new OnFailureListener() {
                                @Override
                                public void onFailure(@NonNull Exception e) {
                                    // Handle failure.
                                }
                            });

        }
    }
}
```

これで記述も完了です、

## 実行
僕はM1のMacで実行してみたのですが、エミュレータを使ってもTwitterログインのための画面は開きませんでした。
しかし、実機で動作確認をしてみたところTwitterログイン用の画面が表示されました。そして自分のアカウントでログインを試してみると、ログイン処理が正常に実行されToastが表示されました。

多分こういう感じでTwitterログインが実装できると思います。

# 参考リンク
> https://www.topgate.co.jp/firebase01-what-is-firebas