這一篇是根據上一篇的後續,如果還沒看過上一篇,請先參閱:
Android Auth(2-1)Google 整合認證-設定環境/UI
這樣我們就可以開始寫程式了,我們要實作 Firebase 整合 Google 認證登入,需要了解三個物件,兩個與 Google 帳號有關,另一個和 Firebase Aentication 相關,分別介紹如下:
SignInButton:這是用來啟動 Google 登入頁的 View,這在前一篇設定 UI 時,己經介紹過了
GoogleApiClient :這是我們用來和 Google 登入溝通協調的工具,包括UI 的產生等
FirebaseAuth:這是我們用來和 Firebase 登入溝通協調的工具
而登入的主流程如下:
- 建立以上三物件的實體
- 由 SignInButton 啟動用 GoogleApiClient 所產出的登入 Intent 並等待回傳
- GoogleApiClient 回傳登入成功與否,若成功就使用該帳號登入 Firebase
- 若成功就顯示相關登入者名稱資訊
另外,還有一個登出的方法需要實作
第一步,來產出物件的實體,SignInButton 我們在介面檔己經作出來了,所以只需要連繫到就可以了,FirebaseAuth 的實體也很簡單,只要用 .getInstance() 方法就可以取得了, GoogleApiClient 就麻煩一點,要先建立一個設定用的 GoogleSignInOptions 的實體,再用Builder 方法來產生,在產生時,還要設定連線失敗回報的機制,程式碼如下:
signInButton = (SignInButton)findViewById(R.id.singinButton); // 設定 FirebaseAuth 介面 mAuth = FirebaseAuth.getInstance(); // 設定 Google 登入 Client GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build(); mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext()) .enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { Toast.makeText(MainActivity.this,"Google 連線異常",Toast.LENGTH_LONG).show(); } }) .addApi(Auth.GOOGLE_SIGN_IN_API,gso) .build();
這些程式都是寫在 OnCreate() 方法內。
接下來要把 signInButton 按下時,啟動登入頁面,同樣的寫在 OnCreate() 內,程式碼如下
signInButton.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view){ Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN); } });
\這兒,我用了一個常數 RC_SIGN_IN 做為回傳判別,需要在 class 最前面,設定這個
private static final int RC_SIGN_IN = 1;
然後,我們就要寫回傳時要做的事了,若成功,就試登入 Firebase,仍是成功就顯示出使者的 display name,在程式中新增兩個方法:
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SIGN_IN){ GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); if (result.isSuccess()){ GoogleSignInAccount account = result.getSignInAccount(); //取得使用者並試登入 firebaseAuthWithGoogle(account); } } } //登入 Firebase private void firebaseAuthWithGoogle(final GoogleSignInAccount account){ AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(),null); mAuth.signInWithCredential(credential) .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (!task.isSuccessful()) { Toast.makeText(MainActivity.this, "Failed", Toast.LENGTH_LONG).show(); }else { Toast.makeText(MainActivity.this, "SingIn name:"+account.getDisplayName(), Toast.LENGTH_LONG).show(); } } }); }
最後是登出的方法
public void firebaseSingOut(View view){ // Firebase 登出 mAuth.signOut(); // Google 登出 GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build(); GoogleSignIn.getClient(this, gso).signOut().addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { Toast.makeText(MainActivity.this, "SingOut", Toast.LENGTH_LONG).show(); } }); }
這樣就完成了我們的程式,執行結果如下
也可以在 Firebase 的控制台中,看到我們登入的帳號:
如此,我們就完成了帳號的登入了。
最後,附上完整的 MainActivity.java
public class MainActivity extends AppCompatActivity { private FirebaseAnalytics mFirebaseAnalytics; private SignInButton signInButton; private Button singOutButton; private static final int RC_SIGN_IN = 1; private GoogleApiClient mGoogleApiClient; private FirebaseAuth mAuth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Obtain the FirebaseAnalytics instance. mFirebaseAnalytics = FirebaseAnalytics.getInstance(this); singOutButton = (Button)findViewById(R.id.singoutButton); signInButton = (SignInButton)findViewById(R.id.singinButton); // 設定 FirebaseAuth 介面 mAuth = FirebaseAuth.getInstance(); // 設定 Google 登入 Client GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build(); mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext()) .enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { Toast.makeText(MainActivity.this,"Google 連線異常",Toast.LENGTH_LONG).show(); } }) .addApi(Auth.GOOGLE_SIGN_IN_API,gso) .build(); signInButton.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View view){ Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN); } }); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SIGN_IN){ GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); if (result.isSuccess()){ GoogleSignInAccount account = result.getSignInAccount(); //取得使用者並試登入 firebaseAuthWithGoogle(account); } } } //登入 Firebase private void firebaseAuthWithGoogle(final GoogleSignInAccount account){ AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(),null); mAuth.signInWithCredential(credential) .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (!task.isSuccessful()) { Toast.makeText(MainActivity.this, "Failed", Toast.LENGTH_LONG).show(); }else { Toast.makeText(MainActivity.this, "SingIn name:"+account.getDisplayName(), Toast.LENGTH_LONG).show(); } } }); } public void firebaseSingOut(View view){ // Firebase 登出 mAuth.signOut(); // Google 登出 GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build(); GoogleSignIn.getClient(this, gso).signOut().addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { Toast.makeText(MainActivity.this, "SingOut", Toast.LENGTH_LONG).show(); } }); } }