簡體   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