android - 使用 Firebase 无效 Idp 响应的 Google 登录

标签 android exception firebase oauth-2.0 firebase-authentication

我目前正在将旧的 Google Plus 登录代码转换为新方式。 我发现很难理解基本原理。它不会起作用。

第一步是解释如何让登录工作: https://developers.google.com/identity/sign-in/android/sign-in

第二步是 Firebase。出于某种原因,您需要将上述文档与以下内容结合起来: https://firebase.google.com/docs/auth/android/google-signin

为什么会这样?它的目的似乎过于复杂:只是登录。 反正。您必须执行以下操作:

在您的 Activity 的 onCreate 中,您需要添加:

GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(webClientId)
                .build();

        mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
                .enableAutoManage(mContext /* FragmentActivity */, this /* OnConnectionFailedListener */)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .build();

        mAuth = FirebaseAuth.getInstance();

在您添加的登录点击处理程序中

Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
mActivity.startActivityForResult(signInIntent, RC_SIGN_IN);

onActivityResult 中你必须添加

if (requestCode == RC_SIGN_IN) {
     GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);

            AuthCredential credential = GoogleAuthProvider.getCredential(result.getSignInAccount().getIdToken(), null);
            mAuth.signInWithCredential(credential)
                    .addOnCompleteListener(mActivity, new OnCompleteListener<AuthResult>() {
                        @Override
                        public void onComplete(@NonNull Task<AuthResult> task) {
                            //do something

                        }
                    });

        }

这里我在使用 getIdToken 调用 GoogleAuthProvider.getCredential 时遇到异常。

com.google.firebase.FirebaseException: An internal error has occurred. [ Invalid Idp Response: the Google id_token is not allowed to be used with this application. Its audience (OAuth 2.0 client ID) is xxxxxxxxxxxx-xxxxxxxxxxxxxx.apps.googleusercontent.com, which is not authorized to be used in the project with project_number: xxxxxxxxxxxx.

只需打印出 token

result.getSignInAccount().getIdToken(); works fine.

我几乎可以肯定这个 web_client_id 是正确的,因为当我替换它时,初始登录请求将失败。

我在 auth -> google -> Web SDK 配置下检查了 Firebase 控制台。 Webclient-ID 和密码与 Google 控制台 webapp 客户端 id 中的相匹配。

有谁知道如何解决这个问题?

最佳答案

好的,在花了几个小时之后,我决定摆脱所有与 firebase 相关的东西。现在可以了。还是不明白为什么你会需要 Firebase 的东西。

对于登录,我有以下内容:

在你的activity或activityFragment中添加:

private static Activity mActivity;
private FragmentActivity mContext;
private GoogleApiClient mGoogleApiClient;
private GoogleSignInResult cachedSignInResult;
private String webClientId = "XXXXXXXXXXXX-xxxxxxxxxxxxxxx.apps.googleusercontent.com";

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(webClientId)
                .build();

    mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
                .enableAutoManage(mContext /* FragmentActivity */, this /* OnConnectionFailedListener */)
                .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
                .build();
}

添加处理登录请求的逻辑。

public void requestLogin(OnLoginCompleteListener onLoginCompleteListener) {

    Log.d(TAG,"request login");

    //already logged in scenarios
    if (isConnected() && cachedSignInResult != null){
        Log.d(TAG,"you are already logged in with "+cachedSignInResult.getDisplayName());
        onLoginCompleteListener.onLoginSuccess()
        return;
    }
    else if (isConnected()){
        Log.d(TAG,"already connected, but no ");
        silentLogin(onLoginCompleteListener);
        return;
    }

    forceRegularLogin(onLoginCompleteListener);
}


public boolean isConnected() {
    if (mGoogleApiClient == null){
        Log.d(TAG,"cannot check isConnected without api client");
        return false;
    }
    return mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected();
}

private void silentLogin(final OnLoginCompleteListener onLoginCompleteListener){

    OptionalPendingResult<GoogleSignInResult> pendingResult =
            Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);

    pendingResult.setResultCallback(new ResultCallback<GoogleSignInResult>() {
        @Override
        public void onResult(@NonNull GoogleSignInResult   googleSignInResult) {

            if (googleSignInResult.isSuccess()){
                Log.d(TAG,"result is ok with name "+googleSignInResult.getSignInAccount().getDisplayName());
                cachedSignInResult = googleSignInResult;
                onLoginCompleteListener.onLoginSuccess()
            }
            else{
                Log.d(TAG,"not logged in silently. do regular login");
                requestLogin(onLoginCompleteListener);
            }
        }
    });
}


private void forceRegularLogin(OnLoginCompleteListener onLoginCompleteListener){
    if (mGoogleApiClient == null){
        Log.d(TAG,"cannot login in. no google api client");
        onLoginCompleteListener.error("no_google_api_client_found");
        return;
    }

    registeredLoginCallback = onLoginCompleteListener; //register for later use in activity result

    Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
    mActivity.startActivityForResult(signInIntent, RC_SIGN_IN);
}

添加 onActivityResult 回调。

 public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG,"on activity result");

    GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);

    if (result.isSuccess()){

        if (registeredLoginCallback != null) {
            registeredLoginCallback.onLoginSuccess();
        }
        else{
            Log.e(TAG,"no callback registered for logging in result ok");
        }
    }
    else{
        if (registeredLoginCallback != null) {
            registeredLoginCallback.error();
        }
        else{
            Log.e(TAG,"no callback registered for logging in result error");
        }
    }
}

添加完成回调的接口(interface)

public interface OnLoginCompleteListener{
     public void onLoginSuccess();
     public void error(String message);
}

现在在您添加的登录按钮回调中

 requestLogin(new OnLoginCompleteListener() {
      @Override
      public void onLoginSuccess() {
          Log.d(TAG,"logged in");
      }
      @Override
      public void error(String message) {
          Log.d(TAG,"error logging in"+message);
      }
 }

另外可以添加如下方法和接口(interface)获取用户个人资料信息

public void requestCurrentPerson(final OnRequestSocialPersonCompleteListener onRequestSocialPersonCompleteListener) {

    Log.d(TAG,"request current person");

    silentLogin(new OnLoginCompleteListener() {
        @Override
        public void onLoginSuccess(i) {

            SocialPerson socialPerson = new SocialPerson();
            socialPerson.id = signInResult.getSignInAccount().getId();
            socialPerson.name = signInResult.getSignInAccount().getDisplayName();
            socialPerson.avatarURL = signInResult.getSignInAccount().getPhotoUrl().toString();
            onRequestSocialPersonCompleteListener.onRequestSocialPersonSuccess(socialPerson);
        }

        @Override
        public void error(String message) {
            onRequestSocialPersonCompleteListener.error("error_fetching_social_person "+message);
        }
    });
}


public interface OnRequestSocialPersonCompleteListener {

    public void onRequestSocialPersonSuccess(SocialPerson socialPerson);
    public void error(String message);
}

登录后调用

requestCurrentPerson(new OnRequestSocialPersonCompleteListener() {
                    @Override
                    public void onRequestSocialPersonSuccess( SocialPerson socialPerson) {
                            Log.d(TAG,"this is my persoin "+socialPerson);
                    }
                    @Override
                    public void error(Message message) {
                            Log.d(TAG,"error_fetching_social_person " +message);
                    }
}

关于android - 使用 Firebase 无效 Idp 响应的 Google 登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40835138/

相关文章:

Android:Kotlin 将数据从 Dialog 传递到 BottomSheetDialogFragment

android - 设置扩展 Dialog 的 CustomDialog 主题的最佳实践是什么 OnClickListener

android - 计算触摸点的角度并在Android中的固定图像或 Canvas 或位图图像上旋转

android - 无法加载 android 套接字类 java.lang.NoSuchMethodException : com. android.org.conscrypt.OpenSSLSocketImpl.setUseSessionTickets [boolean]

android - 基于更改并存储到 map 中的 DataSnapshot 出错

android - 我找不到从 firebase 下载到内部存储的文件

authentication - 如何使用 Firebase 登录多个社交服务?

android - 从应用程序 android 打开当前正在进行的通话

c# - 将本地 dll 放在 ASP.NET 项目中的什么位置?

Java ArrayIndexOutOfBounds 异常