返回

Android Google OAuth 中 NoCredentialException 的全面解决方案指南

Android

Android Google OAuth 中 NoCredentialException:解决之道

导言:

在使用 Android 集成 Google OAuth 进行身份验证时,开发者可能遇到令人抓狂的 NoCredentialException: No credentials available 错误。本文将深入探究此问题的根源,并提供详尽的解决方案,帮助您轻松解决这一难题。

理解 NoCredentialException:

NoCredentialException 表明当调用 credentialManager.getCredential 方法时,系统无法找到任何有效的 Google 凭据。这意味着 Google OAuth 无法向您的应用程序授予访问用户帐户的权限。

解决方案:

1. 启用 Google Play 服务:

确保在 build.gradle 文件中添加以下依赖项:

implementation 'com.google.android.gms:play-services-auth:20.3.0'

2. 配置 OAuth 2.0 凭据:

  • 在 Google Cloud Platform 控制台中,为您的项目启用 OAuth 2.0 凭据。
  • 添加以下类型:
    • Web 应用程序: 用于 Web 服务器的凭据
    • Android 应用程序: 用于 Android 应用程序的凭据
  • 服务器客户端 ID 与代码中设置的 ID 保持一致。

3. 检查权限:

Android 应用程序清单文件中需要以下权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

4. 授予权限:

在设备上运行应用程序时,必须授予访问 Google 帐户的权限。拒绝权限将导致 NoCredentialException

5. 等待凭据缓存在设备上:

首次调用 credentialManager.getCredential 时,系统可能找不到缓存在设备上的凭据。请重新启动应用程序或等待一段时间,让凭据有机会进行缓存。

6. 代码示例:

以下代码演示了如何正确请求 Google 凭据:

private fun googleLogin(context: Context) {
    val googleIdOption = GetGoogleIdOption.Builder()
        .setFilterByAuthorizedAccounts(true)
        .setAutoSelectEnabled(true)
        .setServerClientId("!!!!Web Server Client ID!!!!!")
        .build()

    val request = GetCredentialRequest.Builder()
        .addCredentialOption(googleIdOption)
        .build()

    val credentialManager = CredentialManager.create(context)

    viewModelScope.launch {
        val loginFlow = flow {
            try {
                val result = credentialManager.getCredential(
                    context = context,
                    request = request
                )
                emit(result.credential)
            } catch (e: NoCredentialException) {
                Log.e("TAG", "loginSuccess NoCredentialException", e)
            }
        }.catch { e ->
            if(e is NoCredentialException) {
                Log.e("TAG", "loginSuccess NoCredentialException", e)
            }
        }.collect {
            loginSuccess(it)
        }
    }
}

7. 其他提示:

  • 应用程序目标 SDK 版本应至少为 31。
  • 在 Android 12 及更高版本中,目标 SDK 版本应设置为 33 或更高。

结论:

通过遵循本文概述的步骤,您应该能够有效解决 Android Google OAuth 中的 NoCredentialException 错误。记住,仔细配置 OAuth 凭据、检查权限并等待凭据缓存在设备上至关重要。通过解决此问题,您可以顺利进行 Google OAuth 集成,让您的应用程序获得用户帐户访问权限。

常见问题解答:

  • 问:我已完成所有步骤,但仍然收到 NoCredentialException
    答:请检查服务器客户端 ID 是否与 Google Cloud Platform 中的 ID 完全一致。

  • 问:我需要在代码中进行额外的配置吗?
    答:大多数情况下,上面提供的代码示例已经足够了。但是,您可能需要根据具体要求进行一些微调。

  • 问:在 Android 12 及更高版本中,目标 SDK 版本必须设置为 33 或更高吗?
    答:是的,这是强制要求,否则可能会遇到兼容性问题。

  • 问:如何检查凭据是否缓存在设备上?
    答:可以使用 credentialManager.hasCredential 方法进行检查。

  • 问:我还可以尝试哪些其他方法来解决此问题?
    答:尝试清除应用程序数据并重新安装,或者确保 Google Play 服务已更新到最新版本。