繁体   English   中英

谷歌玩服务游戏signInSilently()失败错误'com.google.android.gms.common.api.ApiException:4:4'

[英]Google play service game signInSilently() FAILED error 'com.google.android.gms.common.api.ApiException: 4: 4 '

I am using google play services signInSilently() , but I got the error signInSilently() Failed com.google.android.gms.common.api.ApiException: 4: 4: , but I am a test user in my application. 我已经在我的 firebase 项目中添加了SHA-1、客户端 ID、客户端密码并启用了使用谷歌登录、谷歌玩游戏服务 我的代码如下,

class SignInGGPlayBan2 : AppCompatActivity() {
    private lateinit var googleSignInClient: GoogleSignInClient
    private lateinit var auth: FirebaseAuth

    companion object {
        private val TAG = "SignInGGPlayBan2"
        private const val RC_SIGN_IN = 9001
    }

    private var btnSignIn: SignInButton? = null
    private var btnGGPlayGameSignOut: Button? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_ggplay)

        val gso = GoogleSignInOptions
            .Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
            .requestServerAuthCode(getString(R.string.default_web_client_id))
            .build()

        googleSignInClient = GoogleSignIn.getClient(this, gso)

        auth = FirebaseAuth.getInstance()

        btnSignIn = findViewById(R.id.btnGGPlayGame)
        btnGGPlayGameSignOut = findViewById(R.id.btnGGPlayGameSignOut)

        btnSignIn!!.setOnClickListener {
            startSignInIntent()
        }
    }

    override fun onStart() {
        super.onStart()
        val currentUser = auth.currentUser
        updateUI(currentUser)
    }

    private fun startSignInIntent() {
        val intent = googleSignInClient.signInIntent
        startActivityForResult(intent, RC_SIGN_IN)
    }

    private fun signInSilently() {
        googleSignInClient.silentSignIn().addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                Toast.makeText(this@SignInGGPlayBan2, "Successful", Toast.LENGTH_SHORT).show()
                firebaseAuthWithPlayGames(task.result!!)
            } else {
                Log.d(TAG, "signInSilently() Failed", task.getException())
                Toast.makeText(this@SignInGGPlayBan2, "Failed", Toast.LENGTH_SHORT).show()
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == RC_SIGN_IN) {
            val result = Auth.GoogleSignInApi.getSignInResultFromIntent(data)
            if (result!!.isSuccess) {
                firebaseAuthWithPlayGames(result.signInAccount!!)
                Toast.makeText(this@SignInGGPlayBan2, "Successful Activity", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this@SignInGGPlayBan2, "Failed Activity", Toast.LENGTH_SHORT).show()
            }
        }

    private fun firebaseAuthWithPlayGames(acct: GoogleSignInAccount) {
        Log.d(TAG, "firebaseAuthWithPlayGames:" + acct.id!!)
        val auth = FirebaseAuth.getInstance()
        val credential = PlayGamesAuthProvider.getCredential(acct.serverAuthCode!!)
        auth.signInWithCredential(credential)
            .addOnCompleteListener(this) { task ->
                if (task.isSuccessful) {
                    Log.d(TAG, "signInWithCredential:success")
                    val user = auth.currentUser
                    updateUI(user)
                } else {
                    Log.w(TAG, "signInWithCredential:failure", task.exception)
                    Toast.makeText(baseContext, "Authentication failed.", Toast.LENGTH_SHORT).show()
                    updateUI(null)
                }
            }
    }

    override fun onResume() {
        super.onResume()
        signInSilently()
    }

    private fun updateUI(currentUser: FirebaseUser?) {
        if (currentUser != null) {
            btnGGPlayGameSignOut!!.visibility = View.VISIBLE 
        } else {
            btnGGPlayGameSignOut!!.visibility = View.INVISIBLE
        }
    }
}

错误

signInSilently() Failed
    com.google.android.gms.common.api.ApiException: 4: 4: 
  at com.google.android.gms.common.internal.ApiExceptionUtil.fromStatus(com.google.android.gms:play-services-base@@17.1.0:4)
  at com.google.android.gms.common.internal.zai.zaf(com.google.android.gms:play-services-base@@17.1.0:2)
  at com.google.android.gms.common.internal.zak.onComplete(com.google.android.gms:play-services-base@@17.1.0:6)
  at com.google.android.gms.common.api.internal.BasePendingResult.zaa(com.google.android.gms:play-services-base@@17.1.0:176)
 at com.google.android.gms.common.api.internal.BasePendingResult.setResult(com.google.android.gms:play-services-base@@17.1.0:135)
 at com.google.android.gms.auth.api.signin.internal.zzi.zzc(com.google.android.gms:play-services-auth@@18.0.0:5)
 at com.google.android.gms.auth.api.signin.internal.zzs.dispatchTransaction(com.google.android.gms:play-services-auth@@18.0.0:6)
 at com.google.android.gms.internal.auth-api.zzc.onTransact(com.google.android.gms:play-services-auth@@18.0.0:13)
 at android.os.Binder.execTransact(Binder.java:565)

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myprojecttest">

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity android:name=".SignInGGPlayBan2">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>  

请给我一个解决这个问题的方法。

我已经为此痛苦了几天。 今天终于想通了。

三个控制台在这里有用:Firebase 控制台/项目设置: https://console.firebase.google4BEC56AD9A2D

谷歌开发者控制台/凭据: https://console.developers.google.com/apis/credentials

链接的应用程序: https://play.google.com/apps/publish/

看起来你正在使用 firebase 和这里一样。 当然,我们将遵循指南: https://firebase.google.com/docs/auth/android/play-games?authuser=0 就我而言,我们使用的是 Play Games 登录。

要修复像 DEVELOPER_ERROR (10) / INTERNAL_ERROR (8) / API_NOT_CONNECTED (17) / SIGN_IN_REQUIRED (4) 这样的 GMS ApiExceptions,请遵循以下清单:

  1. 忽略signingReport任务签名报告,这很重要,否则它会自动使用your.package.name和 SHA 生成~/.android/debug.keystore 2.0 客户端 ID 和错误。
  2. 创建或使用您自己的 Key Store 文件,您可以从 Android Studio / Build / Generate Signed Bundle or APK / Create new... / Choose existing... 创建它,(这里我创建了 2 个文件,一个用于调试,一个用于发布,以下称为 debug.jks 和 release.jks)
  3. 使用keytool -exportcert -alias YOUR_ALIAS -keystore debug.jks -list -v从 debug.jks 获取 SHA1,将调试 SHA1 粘贴到 Firebase 控制台。
    Firebase 控制台 保存配置并正确下载google-service.json到您的 Android Studio。 注意,您只设置了调试 SHA1,但没有设置发行版。 然后运行您的应用程序,此过程将使用调试 SHA1 自动创建 OAuth 2.0 客户端 ID。 您可以刷新 Google Developer Console / Credentials 以检查您所做的事情。
  4. 不要从 Google 开发者控制台/凭据创建 OAuth 2.0 客户端 ID,所有 ID 都应从 Google 服务或链接应用程序自动创建。
  5. Then you should have two Client IDs on Google Developer Console / Credentials: Android client for your.package.name (auto created by Google Service) and Web client (auto created by Google Service) Check you google-service.json file, it'将包含两个client_id ,两者都必须与 Google Developer Console / Credentials 完全相同。
  6. 确保您在 Firebase 控制台,身份验证部分安顿下来。
  7. 现在让我们做链接的应用程序。 就像指南一样: https://firebase.google.com/docs/auth/android/play-games?authuser=0#link_your_firebase_project_to_your_play_publisher_account ,但要注意这里有一个巨大的差异,点击授权你的应用程序后,控制台尝试自动将您的 Google Play App Signing SHA1 添加为客户端 ID(没有 release.jks SHA1,release.jks SHA1 是上传密钥,google play 将使用自己的密钥对 APK/Bundle 进行签名)。 随意创建它,顺便说一句,将链接的应用程序重命名为“您的应用程序名称 - Google Play”是一个很好的爱好。 然后刷新 Google Developer Console / Credentials 进行检查。
  8. 让我们用 release.jks 中的 SHA1 和 debug.jks 中的 'Your App Name - Debug' 链接另外两个应用程序,名为“Your App Name - AdHoc”。
  9. 现在生成签名包或 APK。 确保您的 APK 文件正确签名。 请注意,使用 Android 工作室,在调试模式下Run 'YOUR_PROJECT'将使用~/.android/debug.keystore对 APK 进行签名,其中 SHA1 不是您用来创建客户端 ID 的那个。
  10. 亚行安装APK。

Google Developer Console / Credentials 应该如下图所示:
证书 链接的应用程序应如下图所示:
链接的应用程序

谢谢 GOOGLE 和我的头发,祝你好运。

相对答案:

如何使用上传密钥为您的应用签名

在使用上传密钥签名的应用上测试 Google Play 游戏

使用上传密钥而不是 Google Play 应用签名密钥测试游戏服务

首先,你应该把它放在你的 AndroidManifest.xml

<meta-data android:name="com.google.android.gms.games.APP_ID"
    android:value="@string/app_id" />
<meta-data android:name="com.google.android.gms.version"
   android:value="@integer/google_play_services_version"/>

如果您使用的是 Play 游戏服务v2 SDK,

implementation 'com.google.android.gms:play-services-games-v2:17.0.0'

当我尝试使用 GoogleSignIn API 和 Play Games Services v2 SDK 登录时出现此错误。

使用 v2 SDK,您无法再使用 GoogleSignIn API 登录或注销。 (参见删除登录和注销调用

当您的游戏(首次)启动时会自动触发登录,或者您可以使用GamesSignInClient.signIn()手动触发它。 (参见迁移到 Play 游戏服务登录 v2

所以你的代码可以修改如下:

private void startSignInIntent() {
    PlayGames.getGamesSignInClient(this).signIn()
}

onResumesignInSilently (我将其重命名为checkAuthentication )将被修改如下:

override fun onResume() {
    super.onResume()

    // Since the state of the signed in user can change when the activity is not active
    // it is recommended to try and sign in silently from when the app resumes.
    checkAuthentication()
}

private fun checkAuthentication() {
    PlayGames.getGamesSignInClient(this).isAuthenticated.addOnCompleteListener {
        val isAuthenticated = it.isSuccessful && it.result.isAuthenticated
        if (isAuthenticated) {
            // Continue with Play Games Services

            PlayGames.getPlayersClient(this).currentPlayer.addOnCompleteListener { task ->
                val displayName = if (task.isSuccessful) {
                    task.result.displayName
                } else {
                    handleException(
                        task.exception, "There was an issue communicating with players."
                    )
                    "???"
                }

                updateUI(displayName)
            }
        } else {
            // Disable your integration with Play Games Services or show a
            // login button to ask  players to sign-in. Clicking it should
            // call GamesSignInClient.signIn().

            updateUI(null)
        }
    }
}

(以上修改仅作为示例。它可能不会直接应用于您的代码。)

我认为 Google 关于 Play Games Services v2 SDK 的官方文档存在一些缺陷。 例如:

  1. 关于SavedGames的文档仍然在 v2 中使用signInSilently ,但它已过时(导致'com.google.android.gms.common.api.ApiException: 4: 4 ' )。

  2. 关于 SavedGames 的文档使用GoogleSignInClient指定驱动器 scope,但似乎没有必要(更不用说使用 Play Games Services Sign In v2 就足够了)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM