[Android Studio] Firebase UI Authを実装してみた
はじめに
最近、Firebaseを使用してアプリを作成してみようと思い、まずは認証機能の実装だ!!と意気込んでいたのですが、思ったより躓いてしまったのでメモしておきます。
Firebase初心者なので完全に理解できておらず、ミス等ございましたらコメントください。。
今回は下記サイトを参考に実装しました。
Firebase UI Authとは
公式では、
FirebaseUI は Firebase Authentication SDK の上に構築されるライブラリで、アプリにドロップイン UI フローを追加できます。
と記載があります。
要するにFirebase UI Authを使用すれば、複数のプロバイダ(メールアドレス、Facebook、Twitter、Google等)によるユーザ登録、ログイン、ログイン後のページ遷移などのログインフローを任せることができる機能です。
UIなども勝手に用意してくれるので、工数削減に役立ちますがUIや処理のカスタマイズ性は低いので、自分好みのUIにしたい!自分好みの処理にしたい!というかたは、以下サイトを参考に実装してみてください。
事前準備
・Androidプロジェクトの作成
・FirebaseをAndroidプロジェクトへ追加
(https://firebase.google.com/docs/android/setup?hl=ja)
実装
・依存関係の設定
buid.gradle
plugins {
id 'com.android.application'
id 'com.google.gms.google-services' // gms追加
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
// 今回は多分いらないけど記載してあったので一応載せておきます。。いらないと思うけど
implementation platform('com.google.firebase:firebase-bom:30.1.0')
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-auth'
implementation 'com.firebaseui:firebase-ui-auth:8.0.1'
implementation 'com.facebook.android:facebook-login:14.0.0' // facebookのログイン用
// googleのログインは「'com.google.gms.google-services'」に入っているらしい。。
}
・strings.xmlに文字列を指定
「facebook_application_id」と「facebook_client_token」の値は適当に設定しました。
また、「facebook_client_token」に関してはそもそもいるのか疑問です。。
string.xml
<resources>
<string name="app_name">test_firebase</string>
<string name="facebook_application_id">1000</string>
<string name="facebook_client_token">20000</string>
</resources>
・Layoutファイルの作成
activity_firebase_ui.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirebaseUIActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
・ログイン処理の実装
実装は下記サイト参考に、というかコピペです。
FirebaseUIActivity.java
public class FirebaseUIActivity extends AppCompatActivity {
private final String TAG = "FirebaseUIActivity";
// FirebaseUI Activity の結果コントラクトのコールバックを登録する ActivityResultLauncher を作成します。
private final ActivityResultLauncher<Intent> signInLauncher = registerForActivityResult(
new FirebaseAuthUIActivityResultContract(),
new ActivityResultCallback<FirebaseAuthUIAuthenticationResult>() {
@Override
public void onActivityResult(FirebaseAuthUIAuthenticationResult result) {
onSignInResult(result);
}
}
);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_firebase_ui);
createSignInIntent();
}
public void createSignInIntent() {
// FirebaseUI ログインフローを開始するには、任意のログイン方法を含むログイン インテントを作成します。
// サインインプロバイダーを有効にする。
List<AuthUI.IdpConfig> providers = Arrays.asList(
new AuthUI.IdpConfig.EmailBuilder().build(),
new AuthUI.IdpConfig.PhoneBuilder().build(),
new AuthUI.IdpConfig.GoogleBuilder().build(),
new AuthUI.IdpConfig.FacebookBuilder().build(),
new AuthUI.IdpConfig.TwitterBuilder().build());
// Create and launch sign-in intent
Intent signInIntent = AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(providers)
.build();
signInLauncher.launch(signInIntent);
}
// ログインフローが完了すると、onSignInResult に結果が返されます。
private void onSignInResult(FirebaseAuthUIAuthenticationResult result) {
IdpResponse response = result.getIdpResponse();
if (result.getResultCode() == RESULT_OK) {
// Successfully signed in
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
} else {
// Sign in failed. If response is null the user canceled the
// sign-in flow using the back button. Otherwise check
// response.getError().getErrorCode() and handle the error.
// ...
}
}
public void signOut() {
AuthUI.getInstance()
.signOut(this)
.addOnCompleteListener(new OnCompleteListener<Void>() {
public void onComplete(@NonNull Task<Void> task) {
// ...
}
});
}
public void delete() {
AuthUI.getInstance()
.delete(this)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
// ...
}
});
}
public void themeAndLogo() {
List<AuthUI.IdpConfig> providers = Collections.emptyList();
Intent signInIntent = AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(providers)
.setLogo(R.drawable.my_great_logo) // Set logo drawable
//.setTheme(R.style.MySuperAppTheme) // Set theme // FIXME エラー取れない
.build();
signInLauncher.launch(signInIntent);
}
public void privacyAndTerms() {
List<AuthUI.IdpConfig> providers = Collections.emptyList();
Intent signInIntent = AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(providers)
.setTosAndPrivacyPolicyUrls(
"https://example.com/terms.html",
"https://example.com/privacy.html")
.build();
signInLauncher.launch(signInIntent);
}
public void emailLink() {
// EmailBuilderインスタンスのenableEmailLinkSignInを呼び出すことで、FirebaseUIのメールリンクログインを有効にできます。
ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder()
.setAndroidPackageName(
/* yourPackageName= */ "~~~",
/* installIfNotAvailable= */ true,
/* minimumVersion= */ null)
.setHandleCodeInApp(true) // This must be set to true
.setUrl("https://google.com") // This URL needs to be whitelisted(URLを許可リストに登録する)
.build();
List<AuthUI.IdpConfig> providers = Arrays.asList(
new AuthUI.IdpConfig.EmailBuilder()
.enableEmailLinkSignIn()
.setActionCodeSettings(actionCodeSettings) // 有効な ActionCodeSettings オブジェクトを指定する
.build()
);
Intent signInIntent = AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(providers)
.build();
signInLauncher.launch(signInIntent);
}
public void catchEmailLink() {
List<AuthUI.IdpConfig> providers = Collections.emptyList();
// ディープリンクを取得したら、処理できるように verify を呼び出す必要があります。
// 可能であれば、setEmailLink を介してこれを Google に渡す必要があります。
if (AuthUI.canHandleIntent(getIntent())) {
if (getIntent().getExtras() == null) {
return;
}
@SuppressLint("RestrictedApi") String link = getIntent().getExtras().getString(ExtraConstants.EMAIL_LINK_SIGN_IN);
if (link != null) {
Intent signInIntent = AuthUI.getInstance()
.createSignInIntentBuilder()
.setEmailLink(link)
.setAvailableProviders(providers)
.build();
signInLauncher.launch(signInIntent);
}
}
}
}
・Manifestの編集
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="test.com.test_firebase">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Test_Firebase"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".FirebaseUIActivity">
</activity>
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_application_id"/>
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="@string/facebook_client_token"/>
</application>
</manifest>
・MainActivityの作成
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(getApplication(), FirebaseUIActivity.class);
startActivity(intent);
}
}
参考サイト
Discussion