使用AccessToken检索Firebase用户导致Facebook身份验证引起Firebase错误:“来自Facebook的debug_token响应失败”代码190

时间:2018-11-19 08:44:26

标签: android firebase facebook-graph-api firebase-authentication token

在Android上使用Firebase设置Facebook身份验证,并收到以下令人讨厌的错误:

com.google.firebase.FirebaseException: An internal error has occurred. [ Unsuccessful debug_token response from Facebook:{"error":{"message":"Invalid OAuth access token signature.","type":"OAuthException","code":190,"fbtrace_id":"BLR\/UAx2fzn"}} ]

我的目标不是要消除此错误,而是要能够从Firebase获取有关用户的信息。目前,即使我似乎能够获得一个非空,未过期的令牌,但我的Firebase控制台中没有Facebook用户的条目。 IOW,如何使这条线不失败?

-> mAuth.signInWithCredential(credential)

为重现,我从头开始(注销)启动该应用程序,然后继续执行我的LoginActivity。我选择继续使用Facebook LoginButton,然后选择继续。我目前有我的应用程序逻辑,因此回调成功后,它停留在LoginActivity中,并且出现上述错误。

LoginActivity.java

package com.***.datingapp.activities;

import android.content.Intent;
import android.support.annotation.NonNull;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FacebookAuthProvider;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.***.datingapp.R;

public class LoginActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "Login";

    private EditText loginEmailEditText;
    private EditText loginPasswordEditText;
    private TextView loginStatusTextView;
    private TextView loginDetailTextView;
    private Button loginEmailButton;
    private Button loginRegisterButton;
    private LoginButton loginFacebookButton;
    private Button loginFacebookLogoutButton;

    private FirebaseAuth mAuth;
    private CallbackManager callbackManager;
    private FacebookCallback<LoginResult> facebookCallback;

    private static final int RC_SIGN_IN = 123;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        mAuth = FirebaseAuth.getInstance();
        callbackManager = CallbackManager.Factory.create();

        loginEmailEditText = (EditText) findViewById(R.id.edit_text_login_email);
        loginPasswordEditText = (EditText) findViewById(R.id.edit_text_login_password);
        loginStatusTextView = (TextView) findViewById(R.id.text_view_login_status);
        loginDetailTextView = (TextView) findViewById(R.id.text_view_login_details);
        loginEmailButton = (Button) findViewById(R.id.button_login_email);
        loginRegisterButton = (Button) findViewById(R.id.button_login_email_register);
        loginFacebookButton = (LoginButton) findViewById(R.id.buttonFacebookLogin);
        loginFacebookLogoutButton = (Button) findViewById(R.id.buttonFacebookSignout);

        loginEmailButton.setOnClickListener(this);
        loginRegisterButton.setOnClickListener(this);
        loginFacebookLogoutButton.setOnClickListener(this);

        loginFacebookButton.setReadPermissions("email", "public_profile");
        facebookCallback = new FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                Log.d(TAG, "facebook:onSuccess:" + loginResult + " - " + loginResult.getAccessToken().getToken());
                handleFacebookAccessToken(loginResult.getAccessToken());
            }

            @Override
            public void onCancel() {
                Log.d(TAG, "facebook:onCancel");
                updateUI(null);
            }

            @Override
            public void onError(FacebookException error) {
                Log.d(TAG, "facebook:onError", error);
                updateUI(null);
            }
        };
        loginFacebookButton.registerCallback(callbackManager, facebookCallback);
        LoginManager.getInstance().registerCallback(callbackManager, facebookCallback);
    }

    @Override
    public void onStart() {
        super.onStart();
        // Check if user is signed in (non-null) and update UI accordingly.

        AccessToken fbAccessToken = AccessToken.getCurrentAccessToken();
        if (fbAccessToken != null && fbAccessToken.isExpired())
            handleFacebookAccessToken(fbAccessToken);
        else {
            FirebaseUser currentUser = mAuth.getCurrentUser();
            updateUI(currentUser);
        }

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button_login_email:
                if (loginEmailButton.getText().toString().equals(getText(R.string.login_activity_sign_in)))
                    signIn(loginEmailEditText.getText().toString(), loginPasswordEditText.getText().toString());
                else
                    signOut();
                break;
            case R.id.button_login_email_register:
                createAccount(loginEmailEditText.getText().toString(), loginPasswordEditText.getText().toString());
                break;
            case R.id.buttonFacebookSignout:
                signOut();
        }
    }

    private boolean validateForm() {
        boolean valid = true;

        String email = loginEmailEditText.getText().toString();
        if (TextUtils.isEmpty(email)) {
            loginEmailEditText.setError("Required.");
            valid = false;
        } else {
            loginEmailEditText.setError(null);
        }

        String password = loginPasswordEditText.getText().toString();
        if (TextUtils.isEmpty(password)) {
            loginPasswordEditText.setError("Required.");
            valid = false;
        } else {
            loginPasswordEditText.setError(null);
        }

        return valid;
    }

    private void signIn(String email, String password) {
        Log.d(TAG, "signIn:" + email);
        if (!validateForm())
            return;
        mAuth.signInWithEmailAndPassword(email, password)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            // Sign in success, update UI with the signed-in user's information
                            Log.d(TAG, "signInWithEmail:success");
                            FirebaseUser user = mAuth.getCurrentUser();
                            updateUI(user);
                        } else {
                            // If sign in fails, display a message to the user.
                            Log.w(TAG, "signInWithEmail:failure", task.getException());
                            Toast.makeText(LoginActivity.this, task.getException().getMessage(),
                                    Toast.LENGTH_SHORT).show();
                            updateUI(null);
                        }

                        if (!task.isSuccessful()) {
                            loginStatusTextView.setText(R.string.login_activity_status_auth_failed);
                        }
                    }
                });
    }

    private void createAccount(String email, String password) {
        Log.d(TAG, "createAccount:" + email);
        if (!validateForm())
            return;
        mAuth.createUserWithEmailAndPassword(email, password)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            // Sign in success, update UI with the signed-in user's information
                            Log.d(TAG, "createUserWithEmail:success");
                            FirebaseUser user = mAuth.getCurrentUser();
                            updateUI(user);
                        } else {
                            // If sign in fails, display a message to the user.
                            Log.w(TAG, "createUserWithEmail:failure", task.getException());
                            Toast.makeText(LoginActivity.this, task.getException().getMessage(),
                                    Toast.LENGTH_SHORT).show();
                            updateUI(null);
                        }
                    }
                });
    }

    private void handleFacebookAccessToken(AccessToken token) {
        Log.d(TAG, "handleFacebookAccessToken:" + token);

        AuthCredential credential = FacebookAuthProvider.getCredential(token.getToken());
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            // Sign in success, update UI with the signed-in user's information
                            Log.d(TAG, "signInWithCredential:success");
                            FirebaseUser user = mAuth.getCurrentUser();
                            updateUI(user);
                        } else {
                            // If sign in fails, display a message to the user.
                            Log.w(TAG, "signInWithCredential:failure", task.getException());
                            Toast.makeText(LoginActivity.this, task.getException().getMessage(),
                                    Toast.LENGTH_LONG).show();
                            signOut();
                        }
                    }
                });
    }

    @Override
    protected void onResume() {
        super.onResume();
//        Toast.makeText(LoginActivity.this, "Resuming.",
//                Toast.LENGTH_SHORT).show();
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        callbackManager.onActivityResult(requestCode, resultCode, data);
    }

    public void signOut() {
        mAuth.signOut();
        LoginManager.getInstance().logOut();
        FirebaseAuth.getInstance().signOut();
        updateUI(null);
    }

    private void updateUI(FirebaseUser user) {
        if (user != null) {
            loginStatusTextView.setText(getString(R.string.emailpassword_status_format,
                    user.getEmail(), user.isEmailVerified()));
            loginDetailTextView.setText(getString(R.string.firebase_status_format, user.getUid()));
            loginEmailButton.setText(getText(R.string.login_activity_sign_out));
            loginFacebookButton.setVisibility(View.INVISIBLE);
            loginFacebookLogoutButton.setVisibility(View.VISIBLE);
        } else {
            loginStatusTextView.setText(R.string.login_activity_status_signed_out);
            loginDetailTextView.setText(null);
            loginEmailButton.setText(getText(R.string.login_activity_sign_in));
            loginFacebookButton.setVisibility(View.VISIBLE);
            loginFacebookLogoutButton.setVisibility(View.INVISIBLE);
        }
    }

}

我注意到,当我在回调中包含行handleFacebookAccessToken(loginResult.getAccessToken());时,我得到了错误,但否则没有。但是排除该行似乎不是永久性的解决方案,因为那我该如何检索用户信息?

  • 我已经设置了与App ID和App Secret有关的所有内容。
  • 我已尽可能准确地配置了Facebook应用程序的设置。
  • 我已在清单中添加了所需的元标记。

1 个答案:

答案 0 :(得分:0)

我最终通过以下方式解决了这个问题:

(请打鼓)

通过Facebook开发者控制台删除我的Facebook应用程序,并创建一个新的相同应用程序。然后,我将应用程序ID和密码复制到Facebook登录的Firebase控制台auth中,更新了清单,然后就可以了。

我没有将此解决方案标记为“正确”的答案,因为它没有“解决问题”。我已经直觉地认为这是FirebaseException(内部错误),在我已经三重翻两番检查了我所有的Facebook应用程序的配置设置和代码之后。