Firebase身份验证的最新更改。 Google登录?

时间:2017-01-01 23:30:29

标签: java android firebase firebase-authentication google-signin

我向使用Firebase Google登录身份验证的用户提出了一个问题:

我的应用已经使用了几个月,它正在使用Google登录和电子邮件/密码选项进行Firebase身份验证。然而大约一周前,我注意到Google登录已停止工作。没有更改代码,电子邮件/密码选项也像往常一样工作。

我已经检查了文档(https://firebase.google.com/docs/auth/android/google-signin),它仍然是相同的(我的应用程序从文档中复制了身份验证方法)。

你也遇到过类似的问题吗?如果是,请告诉我如何解决。

以下是我的LoginActivity中与Google登录相关的代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    ...   
    //--------Google Sign In
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestEmail()
            .build();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                    Toast.makeText(LoginActivity.this, "Connection failed!", Toast.LENGTH_SHORT).show();
                }
            })
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();

    mGoogleBttn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            SignIn();
        }
    });

}

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

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    mProgress.setMessage("Signing in with Google Account...");
    mProgress.show();
    // 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 {
            // Google Sign In failed, update UI appropriately
            // ...
            mProgress.dismiss();
            Toast.makeText(LoginActivity.this, "Google sign in failed!", Toast.LENGTH_SHORT).show();
        }
    }
}

private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
    Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId());

    AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());

                    mProgress.dismiss();
                    checkUserExist();

                    // 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()) {
                        Log.w(TAG, "signInWithCredential", task.getException());
                        Toast.makeText(LoginActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                    }
                }
            });
}

private void checkUserExist() {
    final String user_id = mAuth.getCurrentUser().getUid();
    mDatabaseUsers.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.hasChild(user_id)) {
                Intent mainIntent = new Intent(LoginActivity.this, MainActivity.class);
                mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(mainIntent);
            } else {
                Intent setupIntent = new Intent(LoginActivity.this, SetupActivity.class);
                setupIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(setupIntent);
            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}

以下是我的应用和项目级build.gradle文件:https://gist.github.com/anonymous/2c9737e898ca2568129af63e61a30f16

3 个答案:

答案 0 :(得分:2)

OP已找到问题的解决方案并已经回答了问题。我正试图按照OP的要求解释案件,这可能是问题背后的真正原因。在此之前,我们可以了解keystorescertificates

documentation说:

  

Android要求所有APK在使用公钥证书进行数字签名后才能安装。即使您在开发期间构建和运行的应用程序也必须使用证书进行签名。如果您不手动操作,Android Studio会自动使用Android SDK工具生成的调试证书对您的APK进行签名。第一次在Android Studio中运行或调试项目时,IDE会自动在$HOME/.android/debug.keystore中创建调试密钥库和证书,并设置密钥库和密钥密码。公钥证书(也称为数字证书或身份证书)包含公钥/私钥对的公钥,以及标识密钥所有者的一些其他元数据(例如,名称和位置)。证书的所有者持有相应的私钥。

     

签署APK时,签名工具会将公钥证书附加到APK。公钥证书用作&#34;指纹&#34;唯一地将APK与您和您相应的私钥相关联。这有助于Android确保您APK的任何未来更新都是真实的,并且来自原始作者。

     

密钥库是包含一个或多个私钥的二进制文件。

     

每个应用必须在整个生命周期内使用相同的证书,以便用户能够安装新版本作为应用的更新。

回到问题;在研究了OP的问题并与他进行了简短的对话后,我想出了以下推论:

  • 他必须使用一个密钥库/证书进行开发,并为项目设置(firebase控制台)使用不同的证书。
  • 由于Google登录工作状态好几个月但最近停止了,他最近肯定已经更改了密钥库。
  • 发现他刚刚迁移到新的开发设备,因此他现在构建的应用程序可能有一个新的调试密钥库文件和新证书,实际上与项目设置中的不同。

案件仍然是一个谜,后来我知道OP从未在新设备上构建或运行他的应用程序。

  

P.S。 Android Studio会自动在$ HOME / .android / debug.keystore中创建调试密钥库和证书,并在您第一次运行或调试项目时设置密钥库和密钥密码。这意味着您使用的每台计算机都将生成一个新的SHA-1,除非您拥有以前的密钥库文件的副本并使用它。

答案 1 :(得分:1)

好的,我承认一件事 - 它与代码无关......我设法解决了这个问题,并且我将解释如何。

我使用调试器调试了应用程序,因为我在评论中被好人推荐,结果发现在onActivityResult()方法中,Auth.GoogleSignInApi.getSignInResultFromIntent(data)返回了此错误结果代码:

  

状态{statusCode = DEVELOPER_ERROR,resolution = null}

这足以让我们了解在哪里挖掘。我查看了我的Firebase控制台 - &gt;项目 - &gt;项目设置 - &gt; SHA-1指纹。

有趣的是 - 那里有指纹,我之前提到过的指纹。无论如何,我决定检查它是否与我从Android Studio获得的相同 - &gt; Gradle项目 - &gt;在project / app / tasks / android /文件夹中有一个包含SHA-1的signingReport。令我惊讶的是,SHA-1指纹不匹配。无论如何,我从AS复制了它并在Firebase控制台中添加了第二行。你猜怎么着?它现在有用......

我仍然有很多关于为什么会发生这种情况的问题,因为它确实突然发生,正如我之前在我的问题中所解释的那样。

我希望这些信息可以帮助那些遇到类似问题的人。然而,问题已经解决了,但是因为有一个赏金集我将奖励给那个人,他会向我解释这个魔法......

答案 2 :(得分:-1)

可能是这种情况 -

  • 在您的设备中,您只添加了一个未在您的应用中授权的电子邮件帐户。除此之外,您的设备中没有添加其他帐户。
  • 因此,当您点击“使用Google登录”按钮时,它会自动获取该电子邮件帐户。但它没有被授权,所以它失败了。

解决方案 - 在您的设备中添加您的授权帐户。现在,当您点击“使用Gooogle登录”时,它会显示一个弹出窗口并询问您要选择哪个帐户。选择正确的一个,您必须能够登录。 希望有所帮助。