【Android】めんどくさいのでFirebaseのGoogleログインをAPIにしちゃう。

# はじめに
FirebaseでGoogleLoginを実装しようとすると毎回めんどくさいのでAPIみたいにして簡単にしました。せっかくなので少し解説もします。
# ソースコード

```java:SimpleGoogleAuthentication.java
public class SimpleGoogleAuthentication implements ActivityCompat.PermissionCompatDelegate {

    private AppCompatActivity mActivity;
    private String mFirebaseWebClientId;
    private int mSighInCode;
    private FirebaseAuth mAuth;

    private GoogleSignInOptions gso;
    private GoogleApiClient gac;

    private String mEmail;
    private String mDisplayName;


    public SimpleGoogleAuthentication (AppCompatActivity activity, String firebaseWebClientId, GoogleApiClient.OnConnectionFailedListener connectionFailedListener){
        this.mActivity = activity;
        this.mFirebaseWebClientId = firebaseWebClientId;
        
        mAuth = FirebaseAuth.getInstance();

        gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(mFirebaseWebClientId)
                .requestEmail()
                .build();

        gac = new GoogleApiClient.Builder(mActivity)
                .enableAutoManage(mActivity, connectionFailedListener)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .build();
    }

    public void loginGoogleAccount (int sighInCode) {
        this.mSighInCode = sighInCode;
        ActivityCompat.setPermissionCompatDelegate(this);
        Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(gac);
        mActivity.startActivityForResult(signInIntent, mSighInCode);
    }

    public void signoutGoogleAccount() {
        gac.connect();
        gac.registerConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
            @Override
            public void onConnected (@Nullable Bundle bundle) {
                mAuth.signOut();
                if (gac.isConnected()) {
                    Auth.GoogleSignInApi.signOut(gac);
                }
            }

            @Override
            public void onConnectionSuspended (int i) {

            }
        });
    }

    @Override
    public boolean requestPermissions (@NonNull Activity activity, @NonNull String[] permissions, int requestCode) {
        return false;
    }

    @Override
    public boolean onActivityResult (@NonNull Activity activity, int requestCode, int resultCode, @Nullable Intent data) {
        ActivityCompat.setPermissionCompatDelegate(null);
        if (requestCode == mSighInCode) {
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            if (result.isSuccess() && result.getSignInAccount() != null) {
                mEmail = result.getSignInAccount().getEmail();
                mDisplayName = result.getSignInAccount().getDisplayName();
                AuthCredential credential = GoogleAuthProvider.getCredential(result.getSignInAccount().getIdToken(), null);
                mAuth.signInWithCredential(credential)
                        .addOnCompleteListener(mActivity, new OnCompleteListener<AuthResult>() {
                            @Override
                            public void onComplete(@NonNull Task<AuthResult> task) {
                                if (task.isSuccessful()) {
                                    // Success
                                    onLoginSucceed(mEmail, mDisplayName);
                                } else {
                                    // Failed
                                    onLoginFailed();
                                }
                            }
                        });
            } else {
                // Google Sign In failed, update UI appropriately
                // Failed
                onLoginFailed();
            }
        } else {
            // Failed
            onLoginFailed();
        }
        return true;
    }

    private void onLoginFailed () {
        if (mActivity instanceof OnGoogleLoginFinishedListener) {
            ((OnGoogleLoginFinishedListener) mActivity).onGoogleLoginFailed();
        }
    }

    private void onLoginSucceed (String email, String name) {
        if (mActivity instanceof OnGoogleLoginFinishedListener) {
            ((OnGoogleLoginFinishedListener) mActivity).onGoogleLoginSucceed(email, name);
        }
    }

    public interface OnGoogleLoginFinishedListener {
        void onGoogleLoginFailed ();
        void onGoogleLoginSucceed (String email, String name);
    }
}
```

# 使い方

```MainActivity.java
public class MainActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener , SimpleGoogleAuthentication.OnGoogleLoginFinishedListener{
// 省略
    @Override
    public void onGoogleLoginSucceed (String email, String name) {
        // 成功
    }

    @Override
    public void onConnectionFailed (@NonNull ConnectionResult connectionResult) {
        // 通信失敗
    }

    @Override
    public void onGoogleLoginFailed () {
        // ログイン失敗
    }

    private void loginGoogleAccount () {
        SimpleGoogleAuthentication login = new SimpleGoogleAuthentication(MainActivity.this, "ログインのウェブクライアントトークン", MainActivity.this);
        login.signoutGoogleAccount(); // ログアウト
        login.loginGoogleAccount(1);// ログイン
    }
```

# 解説みたいなの
必要なデータをインスタンス化でわたしてログイン、ログアウトを実装。
`onActivityResult`で結果が返ってきますが、このクラスは`Activity`を継承してないので来ません。スーパークラスの実装を見てみると、`delegate`というものがあればそこに優先的に流すように書いてありますので、`ActivityCompat.PermissionCompatDelegate`をインプリメントして処理を**横取り**します。むりやり取ってくる感じですね。以下のように設定してあげます。

```java
// 自分のonResultActivityを渡して設定。
ActivityCompat.setPermissionCompatDelegate(this);

@Override
    public boolean onActivityResult (@NonNull Activity activity, int requestCode, int resultCode, @Nullable Intent data) {
    // onResultActivityが呼ばれたらこっちの勝ちなので、そこでほかに影響しないようにもどす。
    ActivityCompat.setPermissionCompatDelegate(null);
    // ...
}
```