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
相关产品推荐
相关产品推荐

