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

Firebase登录页面已登录检测失效,需实现自动跳转MapsActivity

问题:登录界面加载前检查Firebase登录状态并跳转

我希望修改登录界面代码,在显示登录界面之前检查用户是否已登录,若用户已登录则将其重定向至MapsActivity界面。我正在使用Firebase平台,尝试通过Firebase Authentication实现该功能但未成功,以下是我的Login.java代码:

public class Login extends AppCompatActivity {
    FirebaseAuth authProfile;
    private DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReferenceFromUrl("URL");

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

        final EditText username = findViewById(R.id.username);
        final EditText password = findViewById(R.id.password);
        final Button loginBtn = findViewById(R.id.loginBtn);
        final TextView registerNowBtn = findViewById(R.id.registerNowBtn);

        authProfile = FirebaseAuth.getInstance();

        loginBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                final String usernameTxt=username.getText().toString();
                final String passwordTxt=password.getText().toString();

                if(usernameTxt.isEmpty() || passwordTxt.isEmpty()){
                    Toast.makeText(Login.this, "Please enter username or password", Toast.LENGTH_SHORT).show();
                }
                else{
                    databaseReference.child("users").addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(@NonNull DataSnapshot snapshot) {
                            if(snapshot.hasChild(usernameTxt)){
                                final String getPassword = snapshot.child(usernameTxt).child("password").getValue(String.class);
                                if(getPassword != null && getPassword.equals(passwordTxt)){
                                    FirebaseUser firebaseUser = authProfile.getCurrentUser();
                                    Toast.makeText(Login.this, "Login Successful", Toast.LENGTH_SHORT).show();
                                    startActivity(new Intent(Login.this, MapsActivity.class));
                                    finish();
                                }
                                else{
                                    Toast.makeText(Login.this, "Wrong Password", Toast.LENGTH_SHORT).show();
                                }
                            }
                            else{
                                Toast.makeText(Login.this, "Wrong Password", Toast.LENGTH_SHORT).show();
                            }
                        }

                        @Override
                        public void onCancelled(@NonNull DatabaseError error) {

                        }
                    });
                }
            }
        });

        registerNowBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(Login.this, Register.class));
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        if(authProfile.getCurrentUser()!=null){
            startActivity(new Intent(Login.this, MapsActivity.class));
            finish();
        }
    }
}

问题原因

你的onStart方法里的登录状态检测逻辑本身没问题,但登录流程没有和Firebase Authentication绑定:你直接通过实时数据库校验账号密码,却没有调用Firebase Auth的官方登录接口,导致authProfile.getCurrentUser()始终返回null,无法识别已登录状态。

修复方案

1. 绑定Firebase Auth登录流程

假设你的用户数据库中存储了用户的邮箱(推荐用邮箱作为Firebase Auth的登录凭证),修改登录按钮的点击逻辑,在密码验证通过后调用Firebase Auth的登录方法:

loginBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        final String usernameTxt = username.getText().toString();
        final String passwordTxt = password.getText().toString();

        if (usernameTxt.isEmpty() || passwordTxt.isEmpty()) {
            Toast.makeText(Login.this, "请输入用户名或密码", Toast.LENGTH_SHORT).show();
        } else {
            databaseReference.child("users").addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    if (snapshot.hasChild(usernameTxt)) {
                        // 从数据库获取对应用户的邮箱
                        String userEmail = snapshot.child(usernameTxt).child("email").getValue(String.class);
                        final String getPassword = snapshot.child(usernameTxt).child("password").getValue(String.class);

                        if (getPassword != null && getPassword.equals(passwordTxt)) {
                            // 调用Firebase Auth完成登录
                            authProfile.signInWithEmailAndPassword(userEmail, passwordTxt)
                                    .addOnCompleteListener(Login.this, task -> {
                                        if (task.isSuccessful()) {
                                            Toast.makeText(Login.this, "登录成功", Toast.LENGTH_SHORT).show();
                                            startActivity(new Intent(Login.this, MapsActivity.class));
                                            finish();
                                        } else {
                                            Toast.makeText(Login.this, "登录失败: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                                        }
                                    });
                        } else {
                            Toast.makeText(Login.this, "密码错误", Toast.LENGTH_SHORT).show();
                        }
                    } else {
                        Toast.makeText(Login.this, "用户不存在", Toast.LENGTH_SHORT).show();
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {
                    Toast.makeText(Login.this, "数据库查询失败: " + error.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
});

2. 提前检测登录状态(避免界面闪现)

把登录状态检测移到onCreate最开头,还没加载布局就完成跳转,避免登录界面短暂显示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    // 先初始化Auth实例并检测状态
    authProfile = FirebaseAuth.getInstance();
    if (authProfile.getCurrentUser() != null) {
        startActivity(new Intent(Login.this, MapsActivity.class));
        finish();
        return; // 终止后续代码执行
    }

    // 状态未登录,才加载登录界面布局
    setContentView(R.layout.activity_login);
    // 后续控件初始化等逻辑...
}

3. 可选:添加Auth状态监听(更可靠)

如果需要实时监听登录状态变化,可以添加AuthStateListener:

private FirebaseAuth.AuthStateListener authStateListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    authProfile = FirebaseAuth.getInstance();
    // 定义状态监听逻辑
    authStateListener = firebaseAuth -> {
        FirebaseUser user = firebaseAuth.getCurrentUser();
        if (user != null) {
            startActivity(new Intent(Login.this, MapsActivity.class));
            finish();
        }
    };

    // 先做一次状态检测
    if (authProfile.getCurrentUser() != null) {
        startActivity(new Intent(Login.this, MapsActivity.class));
        finish();
        return;
    }

    setContentView(R.layout.activity_login);
    // 控件初始化...
}

@Override
protected void onStart() {
    super.onStart();
    authProfile.addAuthStateListener(authStateListener);
}

@Override
protected void onStop() {
    super.onStop();
    if (authStateListener != null) {
        authProfile.removeAuthStateListener(authStateListener);
    }
}

注意事项

  • 确保Firebase控制台中已启用Email/Password登录方式(路径:Authentication > 登录方法)。
  • 不要在实时数据库中存储明文密码,建议使用Firebase Auth的密码哈希工具处理后存储,或者直接依赖Firebase Auth的账号管理能力,避免自行维护密码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:57:42