【问题标题】:Execution order firebase auth执行命令firebase auth
【发布时间】:2017-04-11 03:01:36
【问题描述】:

我正在尝试使用 facebook sdk 和 android 中的“用户/密码”选项使用 firebase 身份验证登录。我需要知道用户在启动 MainActivity 之前使用了哪种身份验证。

几天前代码可以正常工作,但我不得不删除 firebase 项目。今天我配置了firebase/facebook sdk,它可以工作了。但是现在代码的执行顺序不同了(我知道很奇怪)。

之前,onComplete 方法(当我验证任务是否成功时)先执行,然后再执行onAuthStateChanged。但是现在先执行onAuthStateChanged 方法,然后启动其他活动,然后验证任务是否成功。我在调试模式下看到了这种行为。

这是代码示例,我提前感谢您的帮助

fbLoginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
        @Override
        public void onSuccess(LoginResult loginResult) {
            //Inicio de sesion con facebook exitoso
            handleFacebookAccessToken(loginResult.getAccessToken());
        }

        @Override
        public void onCancel() {
            //Inicio de sesion con facebook cancelado
            Toast.makeText(getApplicationContext(),R.string.cancel_fb_log,Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onError(FacebookException error) {
            //Inicio de sesion con facebook erroneo
            Toast.makeText(getApplicationContext(),R.string.error_fb_log,Toast.LENGTH_SHORT).show();
        }
    });



private void handleFacebookAccessToken(AccessToken accessToken) {
    relativeLayout.setVisibility(View.GONE);
    relativeLayout1.setVisibility(View.VISIBLE);
    AuthCredential credential = FacebookAuthProvider.getCredential(accessToken.getToken());
    //Iniciar sesión con una credencial
    firebaseAuth.signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
        //metodo que se ejecuta al terminar el proceso
        @Override
        public void onComplete(@NonNull Task<AuthResult> task) {
            if (!task.isSuccessful()){
                //Ocurrio un error al realizar el logueo a firebase con facebook
                Utilities.exceptionFirebaseAdministrator(LoginActivity.this, task, LOG_TAG);
                LoginManager.getInstance().logOut();
            }else{
                pref.edit().putBoolean(getString(R.string.pref_logged_with_facebook),true).apply();
                pref.edit().putBoolean(getString(R.string.pref_logged_with_firebase),false).apply();
            }
            relativeLayout.setVisibility(View.VISIBLE);
            relativeLayout1.setVisibility(View.GONE);
        }
    });
}

fireAuthStateListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();

            if(user != null){

//I try use SharedPreference and validate if is facebook login or other
                    startMainActivity();

            }

        }
    };

@Override
public void onStart() {
    super.onStart();
    //Cuando la clase empieza a "escuchar"
    firebaseAuth.addAuthStateListener(fireAuthStateListener);
}

@Override
public void onStop() {
    super.onStop();
    //Cuando la clase deja de "escuchar"
    firebaseAuth.removeAuthStateListener(fireAuthStateListener);
}

【问题讨论】:

    标签: android authentication firebase firebase-authentication


    【解决方案1】:

    在您的代码中进行此更改,

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
            // this is the login layout change it to yours.
        setContentView(R.layout.activity_login);
    
        // START initialize_auth
        mAuth = FirebaseAuth.getInstance();
        // START auth_state_listener
        mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                  //check if user is  not null 
                if (user != null) {
    
    // below code will triggers as soon as your facebook login task is successful                   
    
    
          // this will return provider as facebook,google,twitter,email ,etc
    
                    String provider = user.getProviders().get(0) ;
    
                      pref.edit().putBoolean(getString(R.string.pref_logged_with_facebook), true).apply();
                      pref.edit().putBoolean(getString(R.string.pref_logged_with_firebase), false).apply();
      //I try use SharedPreference and validate if is facebook login or other
                    startMainActivity();
    
    
                } else {
                    // User is signed out
                    Log.d(LOG_TAG, "user signed_out");
                    // logout user and open login page .
                }
            }
        };
    
    
    }
    
    // [START on_start_add_listener]
    @Override
    public void onStart() {
        super.onStart();
        mAuth.addAuthStateListener(mAuthListener);
    }
    
    // [START on_stop_remove_listener]
    @Override
    public void onStop() {
        super.onStop();
        if (mAuthListener != null) {
            mAuth.removeAuthStateListener(mAuthListener);
        }
    }
    
    
    private void handleFacebookAccessToken(AccessToken accessToken) {
        relativeLayout.setVisibility(View.GONE);
        relativeLayout1.setVisibility(View.VISIBLE);
        AuthCredential credential = FacebookAuthProvider.getCredential(accessToken.getToken());
        //Iniciar sesión con una credencial
        firebaseAuth.signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            //metodo que se ejecuta al terminar el proceso
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (!task.isSuccessful()) {
    
                    // If sign in fails, log message or go back to login page.         
                    //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.
    
                    Utilities.exceptionFirebaseAdministrator(LoginActivity.this, task, LOG_TAG);
                    LoginManager.getInstance().logOut();
                }
                  // this will execute no matter whats happens ,
                relativeLayout.setVisibility(View.VISIBLE);
                relativeLayout1.setVisibility(View.GONE);
            }
        });
    }
    
    } 
    

    【讨论】:

    • 那是另一种形式,它可以工作,谢谢(我如何投票反馈,我现在只点击向上箭头)但有时执行顺序是 onComplete 和后来 onAuthStateChanged 似乎很奇怪。如果用户使用 facebook 或电子邮件/密码步骤注册,有什么方法可以知道 onAuthStateChanged 方法?
    • 是的,你可以使用 user.getProviders().get(0) 检查提供者,返回类型是字符串,在 if(user!=null) 中使用它。请参阅上面的编辑答案
    【解决方案2】:

    FirebaseAuth 做了一项棘手的工作,当您启动应用程序时,firebase AuthStateListener 会首先执行以查找任何更改的状态,即用户是否登录或注销。
    在您的代码中,您在启动时添加 AuthStateListener,这就是为什么每次您的应用启动时它都会覆盖其他方法并首先执行 AuthStateListener。 在启动时添加 AuthStateListener 并在停止方法中删除它始终是一个好习惯,这也是 firebase 工程师推荐的。 您做对了,在需要用户身份验证的应用程序中,始终检查用户状态,然后执行与他们相关的任何任务。

         Override
        public void onStart() {
    super.onStart();
    //Cuando la clase empieza a "escuchar"
    firebaseAuth.addAuthStateListener(fireAuthStateListener);
    

    }

    【讨论】:

    • 但是 onComplete 方法中的块代码在 authstate 完成时执行,但不应该 onConplete 代码执行并且当它完成时触发 authstatechanged?
    • 在活动的 onCreate 方法中编写 firebaseAuthsatateListner 方法。每次您的活动打开时,firebasauthstatListner 都会检查用户的状态。当用户尝试使用 facebook 登录时,如果任务成功,将通知身份验证状态侦听器,并且可以在侦听器中处理处理登录用户的逻辑。
    • 执行流程是这样的...... firebase authStateListener(这次状态用户为空)-您的facebook登录oncomplete方法(如果任务成功)-然后再次firebsaeauthstateListner。(这次状态变化给用户!=null)
    • 问题在于,当我处于调试模式时,我看到 signInWithCredential 先启动,然后 firebssaeauthstateListner 执行并在 onComplete 方法中执行最后一个块代码,当验证用户是否使用 facebook 登录时总是返回 false,因为评估之后执行的代码
    • 首先非常感谢 Sagar,但我看到了这个例子,但在我的代码中非常相似,但问题一直存在,onComplete 方法稍后执行,首先是 onAuthStateChanged
    猜你喜欢
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 2012-07-15
    相关资源
    最近更新 更多