Google アカウントでのログインをサポートしている場合は、ワンタップ ログイン クライアントを使用して、ユーザーがアプリのコンテキストから離れることなく、スムーズにアカウントを作成できるようにすることもできます。
One Tap UI を表示すると、デバイス上の Google アカウントを使用してアプリで新しいアカウントを作成するようユーザーに求めるメッセージが表示されます。ユーザーが続行を選択すると、基本的なプロフィール情報(名前、プロフィール写真、確認済みのメールアドレス)を含む ID トークンが取得されます。このトークンを使用して、新しいアカウントを作成できます。
One Tap アカウント作成の実装は、次の 2 つの部分で構成されています。
- One Tap クライアントをアプリに統合する(このページで説明)。これはワンタップ ログインを使用する場合とほとんど同じですが、構成に若干の違いがあります。
- Google ID トークンからユーザー アカウントを作成する機能をバックエンドに追加します。詳しくは、バックエンドで ID トークンを使用するをご覧ください。
One Tap サインアップはどのような場合に使用すればよいですか?
One Tap サインアップをユーザーに提供するのに最も効果的な場所は、ログインすることで新機能が有効になるコンテキストです。まず、保存した認証情報を使用してユーザーをログインさせます。保存されている認証情報が見つからない場合は、ユーザーに新しいアカウントを作成することを提案します。
始める前に
ワンタップ ログインを使ってみるの説明に沿って、Google API コンソール プロジェクトと Android プロジェクトを設定します。
1. One Tap クライアントを構成する
アカウント作成用にワンタップ クライアントを構成するには、次の操作を行います。
- パスワード認証情報のリクエストは有効にしないでください。(ワンタップ サインアップは、トークンベースの認証でのみ可能です)。
setGoogleIdTokenRequestOptions()
と次の設定を使用して、Google ID トークン リクエストを有効にします。- サーバー クライアント ID を Google API コンソールで作成した ID に設定します。これは Android クライアント ID ではなく、サーバーのクライアント ID です。
- デバイス上のすべての Google アカウントが表示されるようにクライアントを構成します。つまり、承認済みアカウントでフィルタしないでください。
- 必要に応じて、アカウントの確認済みの電話番号をリクエストすることもできます。
Java
public class YourActivity extends AppCompatActivity { // ... private SignInClient oneTapClient; private BeginSignInRequest signUpRequest; @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); oneTapClient = Identity.getSignInClient(this); signUpRequest = BeginSignInRequest.builder() .setGoogleIdTokenRequestOptions(GoogleIdTokenRequestOptions.builder() .setSupported(true) // Your server's client ID, not your Android client ID. .setServerClientId(getString(R.string.your_web_client_id)) // Show all accounts on the device. .setFilterByAuthorizedAccounts(false) .build()) .build(); // ... } }
Kotlin
class YourActivity : AppCompatActivity() { // ... private lateinit var oneTapClient: SignInClient private lateinit var signUpRequest: BeginSignInRequest override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) oneTapClient = Identity.getSignInClient(this) signUpRequest = BeginSignInRequest.builder() .setGoogleIdTokenRequestOptions( BeginSignInRequest.GoogleIdTokenRequestOptions.builder() .setSupported(true) // Your server's client ID, not your Android client ID. .setServerClientId(getString(R.string.your_web_client_id)) // Show all accounts on the device. .setFilterByAuthorizedAccounts(false) .build()) .build() // ... } // ... }
2. One Tap UI の解約状況を追跡する
ユーザーがワンタップ登録の使用をすでに拒否しているかどうかは、プロンプトを閉じるか、プロンプトの外側をタップすることで確認する必要があります。これは、Activity のブール値プロパティのようにシンプルにできます。(下記のワンタップ UI の表示を停止するを参照)。
3. One Tap サインアップ UI を表示する
ユーザーがワンタップによる新しいアカウントの作成を拒否していない場合は、クライアント オブジェクトの beginSignIn()
メソッドを呼び出し、返された Task
にリスナーをアタッチします。通常、アプリは、ワンタップ ログイン リクエストで保存された認証情報が見つからない場合に、このステップを実行します。つまり、ログイン リクエストの失敗リスナーで実行します。
ユーザーがデバイスに 1 つ以上の Google アカウントを設定している場合、One Tap クライアントは成功リスナーを呼び出します。成功リスナーで、Task
の結果から保留中のインテントを取得し、startIntentSenderForResult()
に渡してワンタップ UI を開始します。
ユーザーがデバイスに Google アカウントを設定していない場合、One Tap クライアントは失敗リスナーを呼び出します。この場合、特に対応する必要はありません。アプリのログアウト状態の画面を引き続き表示し、ユーザーは通常のアカウント作成フローで登録できます。
Java
oneTapClient.beginSignIn(signUpRequest)
.addOnSuccessListener(this, new OnSuccessListener<BeginSignInResult>() {
@Override
public void onSuccess(BeginSignInResult result) {
try {
startIntentSenderForResult(
result.getPendingIntent().getIntentSender(), REQ_ONE_TAP,
null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Couldn't start One Tap UI: " + e.getLocalizedMessage());
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// No Google Accounts found. Just continue presenting the signed-out UI.
Log.d(TAG, e.getLocalizedMessage());
}
});
Kotlin
oneTapClient.beginSignIn(signUpRequest)
.addOnSuccessListener(this) { result ->
try {
startIntentSenderForResult(
result.pendingIntent.intentSender, REQ_ONE_TAP,
null, 0, 0, 0)
} catch (e: IntentSender.SendIntentException) {
Log.e(TAG, "Couldn't start One Tap UI: ${e.localizedMessage}")
}
}
.addOnFailureListener(this) { e ->
// No Google Accounts found. Just continue presenting the signed-out UI.
Log.d(TAG, e.localizedMessage)
}
4. ユーザーの応答を処理する
ワンタップ登録プロンプトに対するユーザーの回答は、アクティビティの onActivityResult()
メソッドを使用してアプリに報告されます。ユーザーがアカウントの作成を選択した場合、結果は Google ID トークンになります。ユーザーが登録を拒否した場合(ワンタップ UI を閉じたか、その外側をタップした場合)、結果はコード RESULT_CANCELED
とともに返されます。アプリは両方の可能性に対応する必要があります。
Google ID トークンを使用してアカウントを作成する
ユーザーが Google アカウントで登録することを選択した場合は、onActivityResult()
から One Tap クライアントの getSignInCredentialFromIntent()
メソッドにインテント データを渡すことで、ユーザーの ID トークンを取得できます。認証情報には null 以外の googleIdToken
プロパティがあります。
ID トークンを使用してバックエンドでアカウントを作成し(ID トークンを使用してバックエンドで認証するを参照)、ユーザーをログインさせます。
認証情報には、リクエストした追加情報(アカウントの確認済み電話番号など)も含まれます(利用可能な場合)。
Java
public class YourActivity extends AppCompatActivity { // ... private static final int REQ_ONE_TAP = 2; // Can be any integer unique to the Activity. private boolean showOneTapUI = true; // ... @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQ_ONE_TAP: try { SignInCredential credential = oneTapClient.getSignInCredentialFromIntent(data); String idToken = credential.getGoogleIdToken(); if (idToken != null) { // Got an ID token from Google. Use it to authenticate // with your backend. Log.d(TAG, "Got ID token."); } } catch (ApiException e) { // ... } break; } } }
Kotlin
class YourActivity : AppCompatActivity() { // ... private val REQ_ONE_TAP = 2 // Can be any integer unique to the Activity private var showOneTapUI = true // ... override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQ_ONE_TAP -> { try { val credential = oneTapClient.getSignInCredentialFromIntent(data) val idToken = credential.googleIdToken when { idToken != null -> { // Got an ID token from Google. Use it to authenticate // with your backend. Log.d(TAG, "Got ID token.") } else -> { // Shouldn't happen. Log.d(TAG, "No ID token!") } } } catch (e: ApiException) { // ... } } } // ... }
One Tap UI の表示を停止する
ユーザーがログインを拒否した場合、getSignInCredentialFromIntent()
の呼び出しは CommonStatusCodes.CANCELED
ステータス コードの ApiException
をスローします。この場合、ユーザーに繰り返しプロンプトを表示して煩わせないために、ワンタップ ログイン UI を一時的に表示しないようにする必要があります。次の例では、アクティビティにプロパティを設定して、ユーザーにワンタップ ログインを提供するかどうかを決定します。ただし、値を SharedPreferences
に保存したり、他のメソッドを使用したりすることもできます。
ワンタップ ログイン プロンプトの独自のレート リミットを実装することが重要です。これを行わず、ユーザーが連続して複数のプロンプトをキャンセルした場合、One Tap クライアントは 24 時間以内にユーザーにプロンプトを表示しません。
Java
public class YourActivity extends AppCompatActivity { // ... private static final int REQ_ONE_TAP = 2; // Can be any integer unique to the Activity. private boolean showOneTapUI = true; // ... @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQ_ONE_TAP: try { // ... } catch (ApiException e) { switch (e.getStatusCode()) { case CommonStatusCodes.CANCELED: Log.d(TAG, "One-tap dialog was closed."); // Don't re-prompt the user. showOneTapUI = false; break; case CommonStatusCodes.NETWORK_ERROR: Log.d(TAG, "One-tap encountered a network error."); // Try again or just ignore. break; default: Log.d(TAG, "Couldn't get credential from result." + e.getLocalizedMessage()); break; } } break; } } }
Kotlin
class YourActivity : AppCompatActivity() { // ... private val REQ_ONE_TAP = 2 // Can be any integer unique to the Activity private var showOneTapUI = true // ... override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQ_ONE_TAP -> { try { // ... } catch (e: ApiException) { when (e.statusCode) { CommonStatusCodes.CANCELED -> { Log.d(TAG, "One-tap dialog was closed.") // Don't re-prompt the user. showOneTapUI = false } CommonStatusCodes.NETWORK_ERROR -> { Log.d(TAG, "One-tap encountered a network error.") // Try again or just ignore. } else -> { Log.d(TAG, "Couldn't get credential from result." + " (${e.localizedMessage})") } } } } } } // ... }
次のステップ
ユーザーがワンタップ登録フローを完了すると、Google ID トークンが取得されます。このトークンには、ユーザーのメールアドレス、氏名、プロフィール写真の URL などの基本的なプロフィール情報が含まれます。多くのアプリでは、この情報だけでバックエンドでユーザーを認証し、新しいアカウントを作成できます。
アカウントの作成を完了するために追加の情報(ユーザーの生年月日など)が必要な場合は、ユーザーに登録情報フローを表示して、この追加情報をリクエストします。その後、バックエンドに送信してアカウントの作成を完了します。