android-intentandroid-activitygoogle-one-tap

How to use Google's One Tap sign-in UI without resorting to deprecated API


The following code is copied from Google's official document about how to use One Tap sign-in UI for Android:

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 saved credentials found. Launch the One Tap sign-up flow, or
                // do nothing and continue presenting the signed-out UI.
                Log.d(TAG, e.getLocalizedMessage());
            }
        });

You can see they use deprecated startIntentSenderForResult. I have the following:

final ActivityResultLauncher<Intent> activityResultLauncherGoogleDriveSignIn = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        result -> {
           ...
        }
);

I cannot figure out how to replace startIntentSenderForResult with the above activityResultLauncherGoogleDriveSignIn.

Any tip will be greatly appreciated.


Solution

  • you can use the ActivityResultContracts.StartIntentSenderForResult instead of registerForActivityResult this will take a parameter of Intent sender request see the code below

    ActivityResultLauncher<IntentSenderRequest> launcher = registerForActivityResult(
                new ActivityResultContracts.StartIntentSenderForResult(),
                result -> {
                    if (result.getResultCode() == RESULT_OK){
                        // plug the code from google's official documentation
                    }
                }
        );
    

    and just launch it whenever user click on signin using google

    launcher.launch(new IntentSenderRequest.Builder(result.getPendingIntent().getIntentSender()).build());
    

    the whole code looks like this

    // the user clicks the login button
    button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                signUpRequest = BeginSignInRequest.builder()
                        .setGoogleIdTokenRequestOptions(BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
                                .setSupported(true)
                                .setServerClientId(getString(R.string.default_web_client_id))
                                .setFilterByAuthorizedAccounts(false)
                                .build())
                        .setAutoSelectEnabled(true)
                        .build();
    
                oneTapClient.beginSignIn(signUpRequest)
                        .addOnSuccessListener(LoginPageActivity.this, new OnSuccessListener<BeginSignInResult>() {
                            @Override
                            public void onSuccess(BeginSignInResult result) {
                                launcher.launch(new IntentSenderRequest.Builder(result.getPendingIntent().getIntentSender()).build());
                            }
                        })
                        .addOnFailureListener(LoginPageActivity.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());
                            }
                        });
            }
        });
    
    // the result of clicking the button
    ActivityResultLauncher<IntentSenderRequest> launcher = registerForActivityResult(
                new ActivityResultContracts.StartIntentSenderForResult(),
                result -> {
                    if (result.getResultCode() == RESULT_OK){
                        try {
                            SignInCredential credential = oneTapClient.getSignInCredentialFromIntent(result.getData());
                            String idToken = credential.getGoogleIdToken();
                            if (idToken != null) {
                                AuthCredential firebaseCredential = GoogleAuthProvider.getCredential(idToken, null);
                                mAuth.signInWithCredential(firebaseCredential)
                                        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                                            @Override
                                            public void onComplete(@NonNull Task<AuthResult> task) {
                                                if (task.isSuccessful()) {
                                                    // Sign in success, update UI with the signed-in user's information
                                                    Log.d(TAG, "signInWithCredential:success");
                                                    FirebaseUser user = mAuth.getCurrentUser();
                                                } else {
                                                    // If sign in fails, display a message to the user.
                                                    Log.w(TAG, "signInWithCredential:failure", task.getException());
                                                }
                                            }
                                        });
                            }
                        } catch (ApiException e) {
                            // ...
                        }
                    }
                }
        );