【问题标题】:Firebase authentication, MainActivity calls itself onBackPressedFirebase 身份验证,MainActivity 调用自身 onBackPressed
【发布时间】:2016-11-22 09:59:12
【问题描述】:

我目前正在尝试了解 Android 中 Firebase 的身份验证。目前,身份验证本身就像魅力一样工作。我有一个LoginActivity 和一个MainActivity,如果用户成功通过身份验证,就会调用它们。

这是我的LoginActivity

private static final String TAG = "LoginActivity";
EditText mEmailEdit;
EditText mPasswordEdit;
Button msignInButton;
TextView _signupLink;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;

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

    mAuth = FirebaseAuth.getInstance();

    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if (user != null) {
                Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                intent.putExtra("userID", user.getUid());
                startActivity(intent);
                finish();
                Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
            } else {
                Log.d(TAG, "onAuthStateChanged:signed_out");
            }
        }
    };

    mEmailEdit = (EditText) findViewById(R.id.input_email);
    mPasswordEdit = (EditText) findViewById(R.id.input_password);

    msignInButton = (Button) findViewById(R.id.btn_login);
    msignInButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (validate(mEmailEdit.getText().toString(), mPasswordEdit.getText().toString())) {
                mAuth.signInWithEmailAndPassword(mEmailEdit.getText().toString(), mPasswordEdit.getText().toString()).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (mAuth.getCurrentUser() != null) {
                            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                            intent.putExtra("userid", mAuth.getCurrentUser().getUid());
                            startActivity(intent);
                            finish();
                        }
                    }
                });
            }
        }
    });
}
@Override
public void onBackPressed() {
    // disable going back to the MainActivity
    moveTaskToBack(true);
}

public boolean validate(String email, String password) {
    boolean valid = true;

    if (email.isEmpty() || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
        mEmailEdit.setError("Email is not valid");
        valid = false;
    } else {
        mEmailEdit.setError(null);
    }

    if (password.isEmpty() || password.length() < 4 || password.length() > 10) {
        mPasswordEdit.setError("between 4 and 10 alphanumeric characters");
        valid = false;
    } else {
        mPasswordEdit.setError(null);
    }

    return valid;
}

@Override
public void onStart() {
    super.onStart();
    mAuth.addAuthStateListener(mAuthListener);
}

@Override
public void onStop() {
    super.onStop();
    if (mAuthListener != null) {
        mAuth.removeAuthStateListener(mAuthListener);
    }
}

这是我的MainActivity

private FirebaseAuth mAuth;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    mAuth = FirebaseAuth.getInstance();

    Button button = (Button) findViewById(R.id.logout);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mAuth.signOut();
            Intent intent = new Intent(MainActivity.this, LoginActivity.class);
            startActivity(intent);
            finish();
        }
    });
}

所以我的问题是,在用户成功通过身份验证并调用 MainActivity 后,如果我按返回 关闭 应用程序或返回主屏幕。发生的事情是MainActivity 再次调用自己。因此,在我看到另一个MainActivity 弹出后按下。在我再次按下新的后,它终于关闭并返回主屏幕或我之前使用的任何应用程序。

我通过将android:launchMode="singleInstance" 添加到MainActivityactivity 标记中的manifest 来解决此问题,但我仍然不知道为什么MainActivityandroid:launchMode 不存在时再次调用自身设置,我真的很想了解它。

另一方面,我也很想知道 AuthStateListener 的用途。我不明白为什么在我的应用程序中需要这个。当我finish();LoginActivity 用户登录时,AuthStateChanged 事件永远不会被调用。那么是我用错了还是真的没用?

提前致谢!

【问题讨论】:

    标签: android firebase firebase-authentication


    【解决方案1】:

    当您按下返回时,会调用 LoginActivity。但是,由于您仍然登录到 Firebase,因此 AuthStateListener 将使用 user != null 触发,因此再次调用主要活动。根据您是否希望用户每次都登录,您应该覆盖 MainActivity 中的 onBackPressed() 并调用 firebase 注销函数。

    firebase 登录会在您的应用启动/重新启动时持续存在,并且 authstatelistener 会处理此问题。

    【讨论】:

    • 那么如果我删除AuthStateListener 就不会再发生这种情况了吗?
    • 不应该。但是,请注意 AuthStateListener 是 google 推荐的处理登录/注销的方式。
    • 在按钮单击时让用户登录然后在AuthStateListener 中启动MainActivity 会更好吗?顺便说一句,你的答案是完全正确的。我会尽快标记它。
    • 看看我的编辑 - 我认为我之前的回答是错误的。是的,您应该在 AuthStateListener 中启动 MainActivity,因为当用户没有退出上一个会话时,它也会处理用例。
    • 是的,当我改变它时,我注意到我只是调用了它两次。这就是为什么没有无限循环的原因。要走的路仍然是在AuthStateListener 中启动MainActivity。感谢您指出了这一点。现在一切正常!
    【解决方案2】:

    试试这个...

    @Override
    public void onBackPressed() {
        moveTaskToBack(true);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-06-07
      • 2020-04-01
      • 2022-12-10
      • 2016-09-26
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 2017-03-18
      相关资源
      最近更新 更多