はじめに
FirebaseでGoogleLoginを実装しようとすると毎回めんどくさいのでAPIみたいにして簡単にしました。せっかくなので少し解説もします。
ソースコード
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
をインプリメントして処理を横取りします。むりやり取ってくる感じですね。以下のように設定してあげます。
// 自分のonResultActivityを渡して設定。
ActivityCompat.setPermissionCompatDelegate(this);
@Override
public boolean onActivityResult (@NonNull Activity activity, int requestCode, int resultCode, @Nullable Intent data) {
// onResultActivityが呼ばれたらこっちの勝ちなので、そこでほかに影響しないようにもどす。
ActivityCompat.setPermissionCompatDelegate(null);
// ...
}