1

I am implementing google smart lock on my app, for now, we are only implementing on the app side, to log in the user automatically once he allows saving the credentials, on a reinstall for example. But when I removed the password from password.google.com OR when I run the app on a device where the google account doesn't have credentials stored for that app, the library shows a dialog suggesting others sites and apps emails. I need to disable this behavior, I just want to suggest credentials and emails if they belong to my app.

I'm requesting credentials with the following code:

    private void requestCredentials() {
            CredentialRequest request = new CredentialRequest.Builder()
                   .setPasswordLoginSupported(true)
                   .setIdTokenRequested(true)
                   .build();
            mProgressSmartLock.show();
    credentialsClient.request(request).addOnCompleteListener(credentialsApiRequestCompleteListener());
    }

and the listener:

    public OnCompleteListener<CredentialRequestResponse> credentialsApiRequestCompleteListener(){
            return new OnCompleteListener<CredentialRequestResponse>() {
                @Override
                public void onComplete(@NonNull Task<CredentialRequestResponse> task) {
                // Successfully read the credential without any user interaction, this
                // means there was only a single credential and the user has auto
                // sign-in enabled.
                mProgressSmartLock.dismiss();
                if (task.isSuccessful()) {
                    processRetrievedCredential(task.getResult().getCredential());
                    return;
                }

                    // This is most likely the case where the user has multiple saved
                // credentials and needs to pick one. This requires showing UI to
                // resolve the read request.
                Exception e = task.getException();
                if (e instanceof ResolvableApiException) {
                    ResolvableApiException rae = (ResolvableApiException) e;
                    resolveResult(rae, RC_READ);
                    return;
                }

                // This means only a hint is available
                if (e instanceof ApiException) {
                    Crashlytics.logException(e);
                }
            }
        };
    }

saving credentials :

private void saveCredentials(String email, String password) {
        final Credential credential = new Credential.Builder(email)
                .setPassword(password)
                .build();

        mProgress.show();

        credentialsClient.save(credential).addOnCompleteListener(credentialsApiSaveCompleteListener());
}

listener:

public OnCompleteListener<Void> credentialsApiSaveCompleteListener(){
    return new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
            if (task.isSuccessful()) {
                mProgress.dismiss();
                return;
            }

            Exception e = task.getException();
            if (e instanceof ResolvableApiException) {
                // The first time a credential is saved, the user is shown UI
                // to confirm the action. This requires resolution.
                ResolvableApiException rae = (ResolvableApiException) e;
                resolveResult(rae, RC_SAVE);
            } else {
                // Save failure cannot be resolved.
                mProgress.dismiss();
            }
        }
    };
}

enter image description here

Steven
  • 3,812
  • 23
  • 38
DaniloDeQueiroz
  • 412
  • 4
  • 18
  • Can you add any details like: code used, error problem encountered? [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask), [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) Show the community what you have tried. – MαπμQμαπkγVπ.0 Jun 14 '18 at 09:38
  • Just modified the question, thanks for your tip. – DaniloDeQueiroz Jun 14 '18 at 15:48

2 Answers2

6

To avoid this dialog (which lists all email addresses in order to help fill a form, even if there is no passwords saved), do not resolve if the task's getStatusCode() returns SIGN_IN_REQUIRED.

Sorry, this detail was lost in a recent doc change, thanks for reporting. Will get that updated ASAP, sorry for the confusion.

Steven
  • 3,812
  • 23
  • 38
  • So what I gather is that this API is not useful if my app doesn't support Google/Twitter/etc login and uses its own email/password combination, right? Because it will always return `SIGN_IN_REQUIRED` and show user/password combinations from all my saved logins. Since afaik there is no way to filter that list by "my app's domain" it will return all credentials and not only those related to my app's website, so it's not really useful for my needs. Is there any way to filter by my app's domain so I'm only shown the logins related to my website? – dekaru Nov 21 '18 at 17:21
0

If the credential is not from the app or the app did not save any credential, thestatusCode will be the SIGN_IN_REQUIRED. But if you had saved any credential before, you will receive another INT value from statusCode. You can judge in the Resolveable Exception.

LeoCho
  • 1