Firebaseを使ってログイン機能を作ってみます。 参考:Firebase Authentication
サンプルアプリがあります。サンプルアプリは、パッケージ名を変更するのが結構大変だったので、アプリ登録でサンプルアプリと同名のパッケージ名で登録すると簡単に利用できました。 firebase/quickstart-android
Gradleの設定
参考:Android プロジェクトに Firebase を追加する
buildscriptの dependenciesに、
classpath 'com.google.gms:google-services:3.0.0'
appのdependenciesに、
compile 'com.google.firebase:firebase-core:10.0.1'
appの一番下に、
apply plugin: 'com.google.gms.google-services'
エラーがでた。
Error:Execution failed for task ':app:processDebugGoogleServices'. > Missing api_key/current_key object
参考:Missing api_key/current key with Google Services 3.0.0 google-service.jsonにapi_keyがないぞってことかな?たしかに空になっている。もう一度作成したらapi_keyが入っていた。最初のいらないじゃん。。エラーでなくなった。
コンソールでログイン方法有効化
とりあえず今回はgoogleログインをしてみるので、googleを有効にします。Facebookとかは、Facebookアプリのシークレットとか入れる必要がありますが、googleは何もなく有効になりました。
Googleログイン
参考:Android で Google ログインを使用して認証する
下記もgradleに追加する必要がある。
compile 'com.google.firebase:firebase-auth:10.0.1' compile 'com.google.android.gms:play-services-auth:10.0.1'
下記コードは、完全にGoogleのサンプルと同じですが、とりあえずこれを実行したらログイン機能が実装されていた。これだと、Firebaseのユーザテーブルに登録されちゃうので、自分でデータベース作ってる場合は、使えないけど、お手軽ではあります。自分のデータベースと連携させることもできるらしいので、後で調べる。
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/grey_100" android:orientation="vertical" android:weightSum="4"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:id="@+id/title_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/title_bottom_margin" android:text="@string/google_title_text" android:theme="@style/ThemeOverlay.MyTitleText" /> <TextView android:id="@+id/status" style="@style/ThemeOverlay.MyTextDetail" android:text="@string/signed_out" /> <TextView android:id="@+id/detail" style="@style/ThemeOverlay.MyTextDetail" tools:text="Firebase User ID: 123456789abc" /> </LinearLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:background="@color/grey_300"> <com.google.android.gms.common.SignInButton android:id="@+id/sign_in_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="visible" tools:visibility="gone" /> <LinearLayout android:id="@+id/sign_out_and_disconnect" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:orientation="horizontal" android:paddingLeft="16dp" android:paddingRight="16dp" android:visibility="gone" tools:visibility="visible"> <Button android:id="@+id/sign_out_button" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/sign_out" android:theme="@style/ThemeOverlay.MyDarkButton" /> <Button android:id="@+id/disconnect_button" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/disconnect" android:theme="@style/ThemeOverlay.MyDarkButton" /> </LinearLayout> </RelativeLayout> </LinearLayout>
MainActivity.java
import android.content.Intent; import android.os.Bundle; import android.support.annotation.NonNull; import android.util.Log; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.auth.api.Auth; import com.google.android.gms.auth.api.signin.GoogleSignInAccount; import com.google.android.gms.auth.api.signin.GoogleSignInOptions; import com.google.android.gms.auth.api.signin.GoogleSignInResult; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.ResultCallback; import com.google.android.gms.common.api.Status; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.auth.AuthCredential; import com.google.firebase.auth.AuthResult; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; import com.google.firebase.auth.GoogleAuthProvider; public class MainActivity extends BaseActivity implements GoogleApiClient.OnConnectionFailedListener, View.OnClickListener { private static final String TAG = "GoogleActivity"; private static final int RC_SIGN_IN = 9001; // [START declare_auth] private FirebaseAuth mAuth; // [END declare_auth] // [START declare_auth_listener] private FirebaseAuth.AuthStateListener mAuthListener; // [END declare_auth_listener] private GoogleApiClient mGoogleApiClient; private TextView mStatusTextView; private TextView mDetailTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Views mStatusTextView = (TextView) findViewById(R.id.status); mDetailTextView = (TextView) findViewById(R.id.detail); // Button listeners findViewById(R.id.sign_in_button).setOnClickListener(this); findViewById(R.id.sign_out_button).setOnClickListener(this); findViewById(R.id.disconnect_button).setOnClickListener(this); // [START config_signin] // Configure Google Sign In GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build(); // [END config_signin] mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .build(); // [START initialize_auth] mAuth = FirebaseAuth.getInstance(); // [END initialize_auth] // [START auth_state_listener] mAuthListener = new FirebaseAuth.AuthStateListener() { @Override public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { FirebaseUser user = firebaseAuth.getCurrentUser(); if (user != null) { // User is signed in Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid()); } else { // User is signed out Log.d(TAG, "onAuthStateChanged:signed_out"); } // [START_EXCLUDE] updateUI(user); // [END_EXCLUDE] } }; // [END auth_state_listener] } // [START on_start_add_listener] @Override public void onStart() { super.onStart(); mAuth.addAuthStateListener(mAuthListener); } // [END on_start_add_listener] // [START on_stop_remove_listener] @Override public void onStop() { super.onStop(); if (mAuthListener != null) { mAuth.removeAuthStateListener(mAuthListener); } } // [END on_stop_remove_listener] // [START onactivityresult] @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); if (requestCode == RC_SIGN_IN) { GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); if (result.isSuccess()) { // Google Sign In was successful, authenticate with Firebase GoogleSignInAccount account = result.getSignInAccount(); firebaseAuthWithGoogle(account); } else { // Google Sign In failed, update UI appropriately // [START_EXCLUDE] updateUI(null); // [END_EXCLUDE] } } } // [END onactivityresult] // [START auth_with_google] private void firebaseAuthWithGoogle(GoogleSignInAccount acct) { Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId()); // [START_EXCLUDE silent] showProgressDialog(); // [END_EXCLUDE] AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null); mAuth.signInWithCredential(credential) .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful()); // If sign in fails, display a message to the user. If sign in succeeds // the auth state listener will be notified and logic to handle the // signed in user can be handled in the listener. if (!task.isSuccessful()) { Log.w(TAG, "signInWithCredential", task.getException()); Toast.makeText(MainActivity.this, "Authentication failed.", Toast.LENGTH_SHORT).show(); } // [START_EXCLUDE] hideProgressDialog(); // [END_EXCLUDE] } }); } // [END auth_with_google] // [START signin] private void signIn() { Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN); } // [END signin] private void signOut() { // Firebase sign out mAuth.signOut(); // Google sign out Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(@NonNull Status status) { updateUI(null); } }); } private void revokeAccess() { // Firebase sign out mAuth.signOut(); // Google revoke access Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback( new ResultCallback<Status>() { @Override public void onResult(@NonNull Status status) { updateUI(null); } }); } private void updateUI(FirebaseUser user) { hideProgressDialog(); if (user != null) { mStatusTextView.setText(getString(R.string.google_status_fmt, user.getEmail())); mDetailTextView.setText(getString(R.string.firebase_status_fmt, user.getUid())); findViewById(R.id.sign_in_button).setVisibility(View.GONE); findViewById(R.id.sign_out_and_disconnect).setVisibility(View.VISIBLE); } else { mStatusTextView.setText(R.string.signed_out); mDetailTextView.setText(null); findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE); findViewById(R.id.sign_out_and_disconnect).setVisibility(View.GONE); } } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { // An unresolvable error has occurred and Google APIs (including Sign-In) will not // be available. Log.d(TAG, "onConnectionFailed:" + connectionResult); Toast.makeText(this, "Google Play Services error.", Toast.LENGTH_SHORT).show(); } @Override public void onClick(View v) { int i = v.getId(); if (i == R.id.sign_in_button) { signIn(); } else if (i == R.id.sign_out_button) { signOut(); } else if (i == R.id.disconnect_button) { revokeAccess(); } } }