You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase邮箱密码认证场景下切换页面时onCreate未执行、onDataChanged提前触发导致页面跳转异常问题排查

问题分析与解决方案

我来帮你梳理下这个跳转异常的核心原因,再给出针对性的修复方案:

核心问题拆解

1. 未移除的持久化数据库监听

你在登录成功后给mRef添加了ValueEventListener,但这个监听是持续生效的——即使你finish了SignInActivity,它也不会自动解绑。当你注册新用户时,数据库的Users节点发生更新,这个残留的旧监听会被触发,直接执行里面的页面跳转逻辑,跳过了登录页。

2. 注册后的自动登录行为

Firebase的createUserWithEmailAndPassword方法在创建用户成功后,会自动登录该新账号。这时候你启动SignInActivity时,FirebaseAuth的当前用户已经是新注册的账号,配合残留的监听,就直接触发了主页跳转。


具体修复步骤

步骤1:把持续监听换成单次监听

你只需要在登录时获取一次用户的Type和Name,不需要持续监听数据库变化。用addListenerForSingleValueEvent替换addValueEventListener,这样获取完数据后监听会自动销毁,不会留下隐患:

// 替换SignIn中登录成功后的监听代码
mRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        // 优化查询逻辑:直接根据UID定位,不用遍历所有子节点
        DataSnapshot userSnapshot = snapshot.child("Normal").child(user.getUid());
        if (!userSnapshot.exists()) {
            userSnapshot = snapshot.child("Company").child(user.getUid());
        }
        type = userSnapshot.child("Type").getValue(String.class);
        name = userSnapshot.child("Name").getValue(String.class);
        
        pd.dismiss();
        if ("user".equals(type)){
            Intent intent = new Intent(context, UserMain.class);
            intent.putExtra("name", name);
            startActivity(intent);
            finish();
            Log.e("as","loginUser");
        }else{
            Intent intent = new Intent(context, CompanyMain.class);
            intent.putExtra("name", name);
            startActivity(intent);
            finish();
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {
        pd.dismiss();
        Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

步骤2:注册成功后手动登出新用户

在SignUp的注册成功回调里添加mAuth.signOut(),这样回到登录页时,当前用户处于未登录状态,不会触发自动跳转:

if (task.isSuccessful()){
    Toast.makeText(getApplicationContext(),"Sign Up success!",Toast.LENGTH_LONG).show();
    user = mAuth.getCurrentUser();
    int radioId = Rgroup.getCheckedRadioButtonId();
    Rbtn = findViewById(radioId);
    if ("User".equals(Rbtn.getText().toString())){
        mRef.child("/Normal").child(user.getUid()).child("/Name").setValue(name.getText().toString());
        mRef.child("/Normal").child(user.getUid()).child("/Type").setValue("user");
    }else{
        mRef.child("/Company").child(user.getUid()).child("/Name").setValue(name.getText().toString());
        mRef.child("/Company").child(user.getUid()).child("/Type").setValue("company");
    }
    
    // 新增:注册完成后登出,避免自动登录新账号
    mAuth.signOut();
    
    startActivity(new Intent(SignUp.this, SignIn.class));
    finish();
    Log.e("as","signupUserGotoSignin");
}

步骤3:修复字符串比较的错误

你的代码里用==比较字符串(比如type!="null"),这在Java里是错误的,会导致逻辑判断失效。替换成equals()方法:

// 错误写法
if (type!="null"){
// 正确写法
if (type != null && !"null".equals(type)){

步骤4:登录页初始化时检查登录状态(可选优化)

为了避免其他场景下的自动跳转,你可以在SignIn的onCreate里提前检查当前用户:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sign_in);
    mAuth = FirebaseAuth.getInstance();
    
    // 新增:检查是否已登录,若已登录直接提示或跳转
    FirebaseUser currentUser = mAuth.getCurrentUser();
    if (currentUser != null) {
        Toast.makeText(this, "您已处于登录状态", Toast.LENGTH_SHORT).show();
        // 这里可以添加跳转到主页的逻辑,或者让用户手动登出
        return;
    }
    
    // 其他初始化代码...
}

为什么之前的登出尝试没用?

你之前尝试在返回登录页时登出,可能是登出时机不对,或者没有处理残留的数据库监听。上面的方案从根源解决了监听残留和自动登录的问题,应该能彻底解决跳转异常。

内容的提问来源于stack exchange,提问作者kypgh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 16:22:36