Googleアカウントでのサインインをサポートしている場合は、ワンタップサインインクライアントを使用して、アプリのコンテキストからユーザーを引き離すことのない、摩擦のないアカウント作成エクスペリエンスをユーザーに提供することもできます。
ワンタップUIを表示すると、ユーザーはデバイスのGoogleアカウントの1つを使用してアプリで新しいアカウントを作成するように求められます。ユーザーが続行することを選択した場合、新しいアカウントの作成に使用できる基本的なプロファイル情報(名前、プロフィール写真、確認済みの電子メールアドレス)を含むIDトークンを取得します。
ワンタップアカウント作成の実装には、次の2つの部分があります。
- このページで説明されている、ワンタップクライアントをアプリに統合します。これは、ワンタップサインインを使用する場合とほとんど同じですが、構成にいくつかの違いがあります。
- バックエンドにGoogleIDトークンからユーザーアカウントを作成する機能を追加します。これについては、バックエンドでのIDトークンの使用で説明しています。
ワンタップサインアップはどこで使用すればよいですか?
ワンタップサインアップをユーザーに提供するための最も影響力のある場所は、サインインによって新しい機能が有効になる状況です。まず、保存したクレデンシャルを使用してユーザーにサインインしてみます。保存された資格情報が見つからない場合は、ユーザーの新しいアカウントを作成することを提案します。
あなたが始める前に
「ワンタップサインインの開始」の説明に従って、GoogleAPIコンソールプロジェクトとAndroidプロジェクトを設定します。
1.ワンタップクライアントを構成します
アカウント作成用にワンタップクライアントを構成するには、次の手順を実行します。
- パスワードクレデンシャル要求を有効にしないでください。 (ワンタップサインアップは、トークンベースの認証でのみ可能です。)
setGoogleIdTokenRequestOptions()
と次の設定を使用して、setGoogleIdTokenRequestOptions()
トークンリクエストを有効にします。- サーバークライアントIDをGoogleAPIコンソールで作成したIDに設定します。これはサーバーのクライアントIDであり、Androidクライアント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.ワンタップUIキャンセルを追跡します
プロンプトを閉じるか、プロンプトの外側をタップして、ユーザーがワンタップサインアップの使用をすでに拒否しているかどうかを追跡する必要があります。これは、アクティビティのブールプロパティと同じくらい簡単です。 (下記の「ワンタップUIの表示を停止する」を参照してください。)
3.ワンタップサインアップUIを表示します
ユーザーがワンタップを使用して新しいアカウントを作成することを拒否していない場合は、クライアントオブジェクトのbeginSignIn()
メソッドを呼び出し、それが返すTask
にリスナーをアタッチします。アプリは通常、ワンタップサインインリクエストで保存されたクレデンシャルが見つからない場合、つまりサインインリクエストの失敗リスナーでこの手順を実行します。
ユーザーがデバイスに1つ以上のGoogleアカウントを設定している場合、ワンタップクライアントは成功リスナーを呼び出します。成功リスナーで、 Task
結果から保留中のインテントを取得し、それをstartIntentSenderForResult()
に渡して、 startIntentSenderForResult()
UIを開始します。
ユーザーがデバイスにGoogleアカウントを持っていない場合、ワンタップクライアントは失敗リスナーを呼び出します。この場合、アクションは必要ありません。アプリのサインアウトエクスペリエンスを引き続き表示するだけで、ユーザーは通常のアカウント作成フローでサインアップできます。
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()
メソッドを使用してアプリに報告されます。ユーザーがアカウントの作成を選択した場合、結果はGoogleIDトークンになります。ユーザーがワンタップUIを閉じるか、UIの外側をタップしてサインアップを拒否した場合、結果はコードRESULT_CANCELED
返されRESULT_CANCELED
。アプリは両方の可能性を処理する必要があります。
GoogleIDトークンを使用してアカウントを作成します
ユーザーがGoogleアカウントでサインアップすることを選択した場合、 onActivityResult()
からOne TapクライアントのgetSignInCredentialFromIntent()
メソッドにインテントデータを渡すことで、ユーザーのIDトークンを取得できます。クレデンシャルには、null以外のgoogleIdToken
プロパティが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) { // ... } } } // ... }
ワンタップUIの表示を停止する
ユーザーがサインインを拒否した場合、 getSignInCredentialFromIntent()
を呼び出すと、 CommonStatusCodes.CANCELED
ステータスコードを含むApiException
がスローされます。これが発生した場合は、ワンタップサインインUIの表示を一時的に停止して、プロンプトが繰り返されることでユーザーを煩わせないようにする必要があります。次の例では、アクティビティにプロパティを設定することでこれを実現しています。このプロパティを使用して、ユーザーにワンタップサインインを提供するかどうかを決定します。ただし、 SharedPreferences
値を保存するか、他の方法を使用することもできます。
ワンタップサインインプロンプトの独自のレート制限を実装することが重要です。そうしないと、ユーザーが連続して複数のプロンプトをキャンセルした場合、OneTapクライアントは次の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などの基本的なプロフィール情報が含まれています。多くのアプリでは、この情報でバックエンドのユーザーを認証し、新しいアカウントを作成できます。
アカウントの作成を完了するために追加情報(ユーザーの生年月日など)が必要な場合は、この追加情報を要求するサインアップ詳細フローをユーザーに提示します。次に、それをバックエンドに送信して、アカウントの作成を完了します。