title: Google OneTap SignIn Pass or Error codes: 10 / 16
body: <p>I'm trying to set up a Google OneTap SignIn button to my developed App (I'm not using Firebase to sign in) guiding by this source:
  <a href="https://developers.google.com/identity/one-tap/android/get-started" rel="nofollow noreferrer">https://developers.google.com/identity/one-tap/android/get-started</a></p>
  <p>I've created both OAuth &amp; Web credentials on Cloud Console. To generate OAuth Id I took SHA1 which was provided by Android Studio in signing-in report (I took develop SHA-1, but they are all the same anyway).</p>
  <p>I've put to <code>R.string.default_web_client_id</code> the Client Id from WebAuth (Not an Android Id from OAuth).</p>
  <p>As I use Firebase RTDB for storing some data, I set this SHA-1 there as well. The project name in Manifest, Cloud Console and Firebase Console are the same. From Firebase I downloaded &quot;google-services.json&quot; and put it in app root. On Firebase I also set valid service email.</p>
  <p>This is how I implemented OneTap on login activity:</p>
  <pre><code>class LoginActivity : AppCompatActivity() {
    ...
    private lateinit var oneTapClient: SignInClient
    private lateinit var signUpRequest: BeginSignInRequest
    ...
  
    override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          ...
          oneTapClient = Identity.getSignInClient(this)
          signUpRequest = BeginSignInRequest.builder()
              .setPasswordRequestOptions(BeginSignInRequest.PasswordRequestOptions.builder()
                  .setSupported(false)
                  .build())
              .setGoogleIdTokenRequestOptions(BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
                  .setSupported(true)
                  // Your server's client ID, not your Android client ID.
                  .setServerClientId(getString(R.string.default_web_client_id))
                  // Only show accounts previously used to sign in.
                  .setFilterByAuthorizedAccounts(false)
                  .build())
              // Automatically sign in when exactly one credential is retrieved.
              .setAutoSelectEnabled(false)
              .build()
      }
  
    // THIS CALLED FROM FRAGMENT WHEN GOOGLE BUTTON IS CLICKED
    fun onGoogleClick() {
          when (GoogleApiAvailability().isGooglePlayServicesAvailable(applicationContext)) {
              0 -&gt; {
                  beginGoogleSignIn()
              }
              1 -&gt; {
                  toaster.show(&quot;Google services required&quot;)
              }
              2 -&gt; {
                  toaster.show(&quot;Google services update required&quot;)
              }
          }
      }
  
    private fun beginGoogleSignIn() {
          val tag = &quot;$atag-beginGoogleSignIn&quot;
          oneTapClient.beginSignIn(signUpRequest)
              .addOnSuccessListener(this) { result -&gt;
                  try {
                      startIntentSenderForResult(
                          result.pendingIntent.intentSender, library.GOOGLE_SIGNIN_REQUEST_CODE,
                          null, 0, 0, 0)
                  } catch (e: IntentSender.SendIntentException) {
                      logg.d(atag, &quot;Couldn't start One Tap UI: ${e.localizedMessage}&quot;)
                  }
              }
              .addOnFailureListener(this) { e -&gt;
                  // No Google Accounts found. Just continue presenting the signed-out UI.
                  toaster.show(&quot;Please sign in to your google account on your phone&quot;)
                  logg.d(tag, e.localizedMessage)
              }
      }
  
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
          val tag = &quot;$atag-onActivityResult&quot;
          
          super.onActivityResult(requestCode, resultCode, data)
          // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
          if (requestCode == library.GOOGLE_SIGNIN_REQUEST_CODE) {
              try {
                  val credential = oneTapClient.getSignInCredentialFromIntent(data)
                  token = credential.googleIdToken
                  when {
                      token != null -&gt; {
                          // Got an ID token from Google. Use it to authenticate
                          // with your backend.
                          login = credential.id
                          name = credential.displayName
                          avatarUrl = credential.profilePictureUri.toString()
                          tryToLogin()
                      }
                      else -&gt; {
                          // Shouldn't happen.
                          logg.d(atag, &quot;No ID token!&quot;)
                      }
                  }
              } catch (e: ApiException) {
                  when (e.statusCode) {
                      CommonStatusCodes.CANCELED -&gt; {
                          toaster.show(&quot;Please sign in to your google account on your phone&quot;)
                          logg.d(tag, &quot;One-tap dialog was closed.&quot;)
                          // Don't re-prompt the user.
                      }
                      CommonStatusCodes.NETWORK_ERROR -&gt; {
                          logg.d(tag, &quot;One-tap encountered a network error.&quot;)
                          // Try again or just ignore.
                      }
                      else -&gt; {
                          logg.d(tag, &quot;Couldn't get credential from result.&quot; +
                              &quot; (${e.localizedMessage})&quot;)
                      }
                  }
              }
          }
      }
  }
  </code></pre>
  <p>The main problem is that on some of AVD it works well, on other AVD id gives an Error:</p>
  <pre><code>16: Cannot find a matching credential.
  </code></pre>
  <p>However on this AVD Google Services is up to date, and user is logged in to Google Play</p>
  <p>On real device I got this error:</p>
  <pre><code>10: Caller not whitelisted to call this API.
  </code></pre>
  <p>Google services is also up to date here and user is logged in to Play Store.</p>
  <p>Everywhere I used my real gmail address.</p>
  <p>What can be wrong?</p>
  <p><strong>UPDATE</strong></p>
  <p>Spending a lot of time trying to solve this I have just figured out that OneTap is working on some devices, and is not working on other. Also tried to re-create credentials several times.</p>
  <p>Not having very much time to solve this I just use both OneTap way and alternate way to sign in with Google credentials.</p>
  <pre><code>// In activity
  
  lateinit var oneTapClient: SignInClient
  lateinit var signUpRequest: BeginSignInRequest
  private lateinit var gso: GoogleSignInOptions
  lateinit var mGoogleSignInClient: GoogleSignInClient
  
  private fun initApp() {
      oneTapClient = Identity.getSignInClient(this)
          signUpRequest = BeginSignInRequest.builder()
              .setPasswordRequestOptions(
                  BeginSignInRequest.PasswordRequestOptions.builder()
                      .setSupported(false)
                      .build()
              )
              .setGoogleIdTokenRequestOptions(
                  BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
                      .setSupported(true)
                      // Your server's client ID, not your Android client ID.
                      .setServerClientId(getString(R.string.default_web_client_id))
                      // Only show accounts previously used to sign in.
                      .setFilterByAuthorizedAccounts(false)
                      .build()
              )
              // Automatically sign in when exactly one credential is retrieved.
              .setAutoSelectEnabled(false)
              .build()
          gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
              .requestProfile()
              .requestEmail()
              .requestIdToken(getString(R.string.default_web_client_id))
              .build()
          mGoogleSignInClient = GoogleSignIn.getClient(this, gso)
  }
  
  
  
  // Somewhere else in fragment, 'parent' is reference to activity
  
  // Call this when button clicked
  private fun beginGoogleSignIn() {
          parent.oneTapClient.beginSignIn(parent.signUpRequest)
              .addOnSuccessListener(parent) { result -&gt;
                  try {
                      startIntentSenderForResult(
                          result.pendingIntent.intentSender, state.library.GOOGLE_SIGNIN_REQUEST_CODE,
                          null, 0, 0, 0, null)
                  } catch (e: IntentSender.SendIntentException) {
                      stopSignIn(&quot;Couldn't start One Tap UI: ${e.localizedMessage}&quot;)
                  }
              }
              .addOnCanceledListener(parent) {
                  stopSignIn(&quot;Cancelled&quot;)
              }
              .addOnFailureListener(parent) { e -&gt;
                  // Use alternate sign in
                  val signInIntent = parent.mGoogleSignInClient.signInIntent
                  startActivityForResult(signInIntent, state.library.GOOGLE_ALT_SIGNIN_REQUEST_CODE)
              }
      }
  
  
      override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
         
          super.onActivityResult(requestCode, resultCode, data)
          // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
          if (requestCode == state.library.GOOGLE_SIGNIN_REQUEST_CODE) {
              try {
                  handleOneTapSignIn(data)
              } catch (e: ApiException) {
                  val message: String
                  when (e.statusCode) {
                      CommonStatusCodes.CANCELED -&gt; {
                          message = &quot;Please sign in to your google account on your phone&quot;
                          // Don't re-prompt the user.
                      }
                      CommonStatusCodes.NETWORK_ERROR -&gt; {
                          // Try again or just ignore.
                          message = &quot;One-tap encountered a network error.&quot;
                      }
                      else -&gt; {
                          message = &quot;Couldn't get credential from result.&quot; +
                              &quot; (${e.localizedMessage})&quot;
                      }
                  }
                  stopSignIn(message)
              }
          } else if (requestCode == state.library.GOOGLE_ALT_SIGNIN_REQUEST_CODE) {
              try {
                  handleAlternateSignIn(data)
              } catch (e: ApiException) {
                  if (e.statusCode == 12501) {
                      // Dismissed
                      stopSignIn()
                  } else {
                      stopSignIn(&quot;${e.statusCode}&quot;)
                  }
              }
          }
      }
  
      
      private fun handleOneTapSignIn(data: Intent?) {
          val credential = parent.oneTapClient.getSignInCredentialFromIntent(data)
          val token = credential.googleIdToken
          when {
              token != null -&gt; {
                  // Got an ID token from Google. Use it to authenticate
                  // with your backend.
                  login = credential.id
                  avatarUrl = credential.profilePictureUri?.toString() ?: &quot;&quot;
                  tryToLogin()
              }
              else -&gt; {
                  // Shouldn't happen.
                  stopSignIn(&quot;No ID token!&quot;)
              }
          }
      }
  
      private fun handleAlternateSignIn(data: Intent?) {
          val task = GoogleSignIn.getSignedInAccountFromIntent(data)
          try {
              val account = task.getResult(ApiException::class.java)
              // Signed in successfully, show authenticated UI.
              login = account.email!!
              token = account.idToken ?: &quot;&quot;
              avatarUrl = account.photoUrl?.toString() ?: &quot;&quot;
              tryToLogin()
          } catch (e: ApiException) {
              // The ApiException status code indicates the detailed failure reason.
              // Please refer to the GoogleSignInStatusCodes class reference for more information.
              val message = when (e.statusCode) {
                  CommonStatusCodes.NETWORK_ERROR -&gt; {
                      &quot;Could not reach network&quot;
                  }
                  else -&gt; {
                      &quot;SignIn failed with exception $e&quot;
                  }
              }
              stopSignIn(message)
          }
      }
  </code></pre>
  <p><strong>UPDATE 2</strong></p>
  <p>It seems <code>16: Cannot find a matching credential</code> on Android Emulators is related not to user credentials attempting to sign in, but an app credential in Google Cloud Console.
  The issue is not reproduced in my case when I filled consent page at Google Cloud Console as described at <a href="https://developers.google.com/identity/one-tap/android/get-started" rel="nofollow noreferrer">Get started with One Tap sign-in and sign-up</a>
  (I have left empty fields for links to EULA, etc.). Then I have changed package name (for another reasons), then double check that this package name was the same in both credentials configs on Google Cloud Console and in google-services.json. Also I checked that google-services.json is located under <code>[project_root]/app</code> directory.</p>
  <p>I will check this on real device in a few days.</p>