用于 Google 登录的 Android Firebase 身份验证失败

Posted

技术标签:

【中文标题】用于 Google 登录的 Android Firebase 身份验证失败【英文标题】:Android Firebase Authentication for Google Signin fails 【发布时间】:2017-02-15 11:02:55 【问题描述】:

我从上到下遵循firebase documentation,并为我的应用实现了一个简单的谷歌登录选项。但是,当我尝试登录时,在选择谷歌帐户后进程停止并导致 onActivityResult 方法内部出现错误:

if (requestCode == RC_SIGN_IN) 
       GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
       if (result.isSuccess()) 
            // Google Sign In was successful, authenticate with Firebase
            GoogleSignInAccount account = result.getSignInAccount();
            firebaseAuthWithGoogle(account);
        else 
            //THE CODE BREAKS HERE
            // Google Sign In failed, update UI appropriately
       

代码在if (result.isSuccess()) 条件处中断。为了进一步详细说明,这是我在阅读文档后实现的完整代码:

onCreate:

public class TestLogin extends AppCompatActivity 

    private SignInButton mGoogleBtn;
    private static int RC_SIGN_IN = 226;
    private GoogleApiClient mGoogleApiClient;
    private  String TAG = "Checkmate";
    private FirebaseAuth mAuth;
    private FirebaseAuth.AuthStateListener mAuthListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_login);

        mAuth = FirebaseAuth.getInstance();
        mAuthListener = new FirebaseAuth.AuthStateListener() 
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) 
                if(firebaseAuth.getCurrentUser() != null)
                    //success
                
            
        ;

        mGoogleBtn = (SignInButton) findViewById(R.id.googleBtn);

        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken("MY_CLIENT_ID-MY_CLIENT_ID.apps.googleusercontent.com")
                .requestEmail()
                .build();

        mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
                .enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() 
                    @Override
                    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) 
                        //Failed
                    
                )
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .build();

        mGoogleBtn.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                statusMessage.setText("Loading..");
                signIn();
            
        );
    

登录方法:

当点击 Google 登录按钮时调用 SignIn 方法:

    private void signIn() 
        Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
        startActivityForResult(signInIntent, RC_SIGN_IN);
    

onActivityResult:

点击按钮后收到结果时调用onActivityResult。这是发生错误的地方:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) 
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            if (result.isSuccess()) 
                // Google Sign In was successful, authenticate with Firebase
                GoogleSignInAccount account = result.getSignInAccount();
                firebaseAuthWithGoogle(account);
             else 
                //THE CODE BREAKS HERE
                // Google Sign In failed, update UI appropriately
            
        
    

为 Google 处理 Firebase 登录代码:

此方法永远不会被调用,因为代码在 onActivityResult 条件下中断。

    private void firebaseAuthWithGoogle(final GoogleSignInAccount acct) 

        AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() 
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) 
                        
                        // If sign in fails, display a message to the user. If sign in succeeds
                        // the auth state listener will be notified and logic to handle the
                        // signed in user can be handled in the listener.
                        if (!task.isSuccessful()) 
                            Toast.makeText(TestLogin.this, "Authentication failed.",
                                    Toast.LENGTH_SHORT).show();
                        
                    
                );
    

    @Override
    protected void onStart() 
        super.onStart();
        mAuth.addAuthStateListener(mAuthListener);
    

清单

是的,我将 google_services.json 文件添加到 /app 目录

是的,我在 Google 凭据页面中创建了一个新的 OAuth 客户端密钥

这是我的 gradle:

dependencies 
    compile 'com.google.android.gms:play-services:9.6.1'
    compile 'com.google.firebase:firebase-core:9.6.1'
    compile 'com.google.firebase:firebase-database:9.6.1'
    compile 'com.google.firebase:firebase-auth:9.6.1'
    compile 'com.google.firebase:firebase-storage:9.6.1'

apply plugin: 'com.google.gms.google-services'

还有..

buildscript 
    repositories 
        jcenter()
    
    dependencies 
        classpath 'com.android.tools.build:gradle:2.1.3'
        classpath 'com.google.gms:google-services:3.0.0'
    

【问题讨论】:

您是否尝试过访问 GoogleSignInResult 对象以查看是否有任何迹象表明出了什么问题?例如result.getStatus().getStatusMessage(); 我使用result.getStatus() 登录并返回消息:StatusstatusCode=unknown status code:12501, resolution=null@IvanWooll 虽然我没有使用result.getStatus().getStatusMessage(); 登录 这个相关问题的答案表明您的客户端 ID、包名称或 SHA1 密钥有问题。确认全部正确:***.com/q/33846801/4815718 【参考方案1】:

在我之前使用 Firebase FriendlyChat 的测试应用程序中,我在登录时遇到了类似的失败,但我通过谷歌 API 控制台 (https://console.developers.google.com/apis/credentials?project=) 解决了这个问题,然后下载“client_secret.json”(在我的情况下,我需要要为您的 Android 客户端重命名下载的文件名“client_secret_xxxxx.json”),将此文件放在您的 AndroidStudio 项目中的“/src/main/resources”下(如果不存在,则创建“resources”文件夹)然后尝试编译并运行您的 Android再次应用。

总结:您需要 2 个 json 文件:来自 Firebase 控制台的“google-services.json”和来自 Google API 控制台的“client_secret.json”。

希望这能解决您的问题。

【讨论】:

别忘了在 Firebase 控制台中添加您的证书 SHA1 指纹。 身份验证再次失败!【参考方案2】:

检查google API console中是否启用了“Identity Toolkit API”

【讨论】:

【参考方案3】:

首先转到 firebase 控制台并启用登录提供程序。 https://console.firebase.google.com/u/2/project/ipay-71f01/authentication/providers

我有同样的问题,但这是我的解决方案。 谢谢

【讨论】:

【参考方案4】:

确保您已输入签名密钥库的 SHA1。 这是指南https://developers.google.com/android/guides/client-auth

你必须找到两个目录, 1.安装JDK的目录 2. .android

如果您使用的是 Windows,“.android”文件夹可能会放在“C:\Users\username\”中,JDK 目录可能会放在“C:\Users\Program files\java\”中。

在我的例子中,我的操作系统是 Windows,所以首先我在寻找我的 jdk 文件夹。

在 'jdk_folder\bin\' 你会找到 'keytool.exe' 我使用了这个命令

'.\keytool -exportcert -list -v -alias androiddebugkey -keystore C:\Users\sgc109\ .android\debug.keystore'。

然后,复制 SHA1 密钥并粘贴到 firebase 控制台(设置 - 常规 - 我的应用程序 - SHA 证书指纹(?)'(我住在韩国,所以菜单的名称可能与我不同)并且它有效 :)

【讨论】:

以上是关于用于 Google 登录的 Android Firebase 身份验证失败的主要内容,如果未能解决你的问题,请参考以下文章

java 示例登录Android上的Google登录活动,该活动检索用于服务器端身份验证的授权代码。见htt

Xamarin.Auth OAuth Google API,用于Android的用户身份验证

Android中图像视图的边框?

用于在 GAE 上运行的 Go 中验证 Google 登录令牌的包

Google 登录 GoogleIdToken 后端验证突然失败

使 Google 登录对话框不可取消