42

接近认证的最后阶段,但handleSignInResult方法出现问题。它在日志中返回异常代码 10(开发人员错误)。谷歌提供了全面的描述:

应用程序配置错误。此错误不可恢复,将被视为致命错误。开发者是个白痴...

我应该怎么做才能处理这个(获取帐户)并最终从帐户中检索值?
预先感谢您的帮助!!!

主要活动:

package ru.podgorny.carcall;

import ...

public class MainActivity extends AppCompatActivity {

        SignInButton signInButton;
        public static final int RC_SIGN_IN = 07;
        public static final String TAG = "MainActivity";
        TextView tw1;
        TextView tw2;


        GoogleSignInOptions gso;
        GoogleSignInClient mGSC;


        @Override
        protected void onCreate (Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "Activity Works");
        findViews();

            gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestEmail()
                    //.requestProfile()
                    .build();

            mGSC = GoogleSignIn.getClient(this, gso); //smth with mGSC variable....

             View.OnClickListener onClickListener = new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onClick2(v);
                }
            };
             signInButton.setOnClickListener(onClickListener);




    }

    private void findViews() {
            Log.d (TAG, "findViews started");
        signInButton = findViewById(R.id.idButtonGoogle);

        tw1 = findViewById(R.id.textView1);
        tw1 = findViewById(R.id.textView2);

        Log.d(TAG, "Views finded");


    }

    public void onClick2(View view) {
            Log.d(TAG, "onClick started");
        switch (view.getId()) {
            case R.id.idButtonGoogle:
                signIn();
                break;
        }
        Log.d(TAG, "OnClick Started");
    }

    public void signIn() {

        Intent signInIntent = mGSC.getSignInIntent();
        startActivityForResult(signInIntent, RC_SIGN_IN);
        Log.d(TAG, "startActivityForResult works");

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d(TAG, "OnActivityResult started");
        // Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            // The Task returned from this call is always completed, no need to attach
            // a listener.
            Log.d(TAG, "TASK started");
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            handleSignInResult(task);
            Log.d(TAG, "OnActivityResult returned");
        }
    }

    private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
        try {
            GoogleSignInAccount account = completedTask.getResult(ApiException.class);//ERROR -- Code 10
            Log.d(TAG, "Account received");


            updateUI(account);
            Log.d(TAG, "updateUI Launched");
        } catch (ApiException e) {

            Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());
            updateUI(null);
        }
    }

    private void updateUI(GoogleSignInAccount account) {
            if (account!=null) {
                tw1.setText("OK");
                tw2.setText("Name: " + account.getGivenName() + ", Family name: " + account.getFamilyName() + ", Email: " + account.getEmail() /*+ " image: " +
                        account.getPhotoUrl()*/);
            }else {
                tw1.setText("SMTH wrong");
            }

        }

}
4

15 回答 15

60

如果您在console.developers.googleconsole.firebase.google.com使用的项目不同,则可能会发生此错误。如果两个控制台上的项目相同,请确保您已正确添加SHA1密钥。从 Android 工作室获取SHA1 。

  1. 打开安卓工作室
  2. 打开你的项目
  3. 单击 Gradle(从右侧面板,您将看到 Gradle 栏)
  4. 单击 Refresh(从 Gradle Bar 中单击 Refresh,您将看到 List Gradle 项目的脚本)
  5. 单击您的项目(您的项目名称表单列表(根))
  6. 点击任务
  7. 点击安卓
  8. 双击signingReport(您将在运行栏中获得SHA1和MD5(有时会在Gradle控制台中))
  9. 从模块选择下拉列表中选择应用程序模块以运行或调试您的应用程序您还需要从 firebase 控制台获取 google-services.json 并将其放入您的项目中。
于 2018-03-23T13:33:40.287 回答
19

我遇到了同样的问题并浪费了几个小时。在深入研究 OAuth 和 OpenId 时,我找到了原因。我们在这里犯了一个概念错误。

对于 android 或任何其他平台(web 除外),您需要在 google API 控制台的同一个项目中创建至少两种类型的客户端 ID。这些客户 ID 类型是:

  1. Web应用程序
  2. 安卓

您可以按任何顺序创建它们。在创建 Android 类型的 Client Id 时,您需要提供包名和 SHA1。创建 Web 应用程序 ID 时,您只需要提供一个名称。

在您想在后端验证用户之前,您不需要对这些 id 做任何进一步的事情。换句话说,如果您希望您的后端服务器向 google 服务器询问该用户的信息,那么只有您需要 Web 应用程序 ID。概念流程如下:

  1. 首先使用 requestIdToken(your_web_app_client_id) 将 Web 应用程序客户端 ID 从 Android 应用程序发送到 Google 登录服务器作为附加选项。
  2. 用户登录后,您将在 Android 应用程序中取回一个令牌。
  3. 将此令牌发送到您的后端。
  4. 现在您的后端可以与 Google 服务器交换此令牌以获取用户信息

将此 Web 应用程序客户端 ID 从 Android 应用程序发送到后端服务器。

如果您想在后端验证用户,请使用此 Web 应用程序 ID。

于 2019-12-11T22:41:20.983 回答
5

我的答案是你实际上需要结合这里给出的两个主要答案:

  1. 确保您为 Android 创建了 Google OAuth 客户端 ID(一个用于调试,一个用于发布),然后确保它们已按照接受的答案中的说明分配了正确的 SHA1。

  2. 然后,您还需要为 Web 创建一个 OAuth 客户端 ID,并将其用于实际登录:

    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestIdToken(WEB_CLIENT_ID)
        .requestEmail()
        .build();               
    
于 2020-11-13T20:06:36.640 回答
3

我以这种方式解决了这个问题

 GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.AUTH_ID))
                .requestEmail()
                .build();

我的 AUTH_ID 在哪里在此处输入图像描述

于 2020-11-20T17:59:57.930 回答
3

我找到了问题的另一个根源。

在我的情况下,键没问题,但是build.gradle脚本中的applicationId字段与应用程序的包名称不同。

小型研究表明,applicationId字段值在应用程序包名称之前具有某种“优先级”,与 Google autentication 有关。

在build.gradle中注释applicationId行后,应用程序通过包名称在 Google 中对自身进行身份验证。

于 2020-11-06T14:03:44.813 回答
2

选项:然后请记住,谷歌还使用另一个证书签署应用程序。因此,您还需要添加第二个指纹。否则,您将收到此错误。

于 2020-07-28T09:04:05.700 回答
2

此错误的另一个来源是将applicationIdSuffix添加到 gradle 文件中的Build Variants (Flavors)。如果您一切正常,但在添加风味时突然 Google 登录中断,请检查此配置变量。

applicationIdSuffix参数可能需要每个后缀的唯一证书。我只是删除了它,因为我还不需要部署不同的产品或版本。此外,您可以以编程方式为每种风味设置相同的配置。

配置证书构建类型:强制使用相同的证书来签署为特定“productFlavor”配置的不同“buildTypes”?

于 2020-07-14T14:14:48.850 回答
2

使用以下步骤将您debug.keystore的 SHA1 和 SHA256 指纹添加到您的 Firebase 项目:

  1. 获取 debug.keystore 的指纹:Linux/Mac - keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore, Windows -keytool -list -v -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore
  2. 将这些指纹添加到您的 Firebases 项目的 Android 应用部分:https ://support.google.com/firebase/answer/9137403?hl=en
于 2020-07-18T04:08:17.033 回答
2

在此处输入图像描述

我将发布密钥库 sha1 粘贴到谷歌控制台,但忘记添加调试配置!

于 2021-05-06T09:18:23.207 回答
1

我想添加关于为什么@Patrick R 答案的补充信息(以上有效/标记为正确)。要执行您的项目/实践,Google 控制台需要在您的应用程序在 Google Play Market 上分发时通过 SHA-1 密钥来标识您的应用程序,但是,当您只是尝试登录确认和概念证明时,它会关联调试 SHA-1密钥(您的应用程序会自动生成)用于此确切目的,从而使您的测试和生产更改保持模块化。

于 2018-05-16T03:00:11.633 回答
1

这个问题可以通过使用 WebApplication ID 和 android Client ID 来解决

当您将项目配置为为 android app 生成 id 时,它会生成 2 种类型的 id 1 Android 2 WebApplication ,

我们需要使用第二个而不是第一个,它将解决您的问题

于 2021-03-04T07:55:01.153 回答
1

确保您使用来自https://console.cloud.google.com的 Web 客户端 ID,而不是 Android 客户端。即使在类型栏中提到了 Web 应用程序: 在此处输入图像描述

于 2021-10-21T17:59:40.837 回答
0

有同样的问题。签名 apk 中的代码 10。我将所有四个密钥从 Google Play 控制台(设置 -> 应用程序完整性 -> 播放应用程序签名)放入 Firebase 项目,并将新Google-services.json的密钥粘贴到 Android Studio 的应用程序文件夹中,然后在生成签名 Apk 后,谷歌登录工作。

于 2021-03-14T04:28:12.020 回答
0

至少在调试版本上,我没有发送任何令牌并且它工作......即,GoogleSigninOptions.build() 中没有'requestIdToken'

它可能在 Release 中不起作用...将尝试..

于 2021-11-04T03:28:28.523 回答
-1

尝试添加.requestIdToken(getString(R.string.default_web_client_id)).

    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id)) //add this line
            .requestEmail()
            .build();               
于 2020-08-07T16:27:30.097 回答