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

如何通过条件获取Firebase子节点值并实现角色跳转登录

问题描述

用户希望实现登录页面功能:用户通过邮箱/密码登录后,根据其“role”字段值(分为Flood Victim、Rescuer、Admin)跳转到对应页面,其中Flood Victim对应HomeActivity.class,Rescuer对应HomeRes.class。当前无法正确从Firebase数据库获取用户的role字段值完成页面跳转,以下是相关代码及数据库结构截图。

原LoginActivity代码

mAuth.signInWithEmailAndPassword(userEmail, userPswd)
    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
      @Override
     public void onComplete(@NonNull Task<AuthResult> task) {
    if (task.isSuccessful()) {
         //Sign in success, update UI with the signed-in user's information
      Toast.makeText(LoginActivity.this, "Login Successfull!",Toast.LENGTH_SHORT).show();

        FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
        DatabaseReference reference = firebaseDatabase.getReference().child("User");

       //check if user has success registered

      reference.orderByChild("userName").equalTo(userEmail).addListenerForSingleValueEvent(new ValueEventListener()  {
      @Override
      public void onDataChange(@NonNull DataSnapshot snapshot) {
        if (snapshot.exists()) {
          Log.d("User exists", "Welcome!");
           String value =  snapshot.child("userRole").getValue().toString();

            if (value.equals("Flood Victim") && value != null) {
                 startActivity(new Intent(LoginActivity.this, HomeActivity.class));
                      finish();
           } else if (value.equals("Rescuer")) {
                startActivity(new Intent(LoginActivity.this, homeRescuer.class));
                      finish();
                  } else {
                  startActivity(new Intent(LoginActivity.this, homeFv.class));
                         finish();
                    }
                 }
            }

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

}else {
   // If sign in fails, display a message to the user.
      Toast.makeText(LoginActivity.this, "Error" + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
       }
 }
                    });
        }
    }
}

数据库结构截图

数据库用户节点结构


问题分析与修复方案

核心问题点

  1. 查询结果处理错误:orderByChild("userName").equalTo(userEmail)返回的是包含匹配用户节点的快照,直接调用snapshot.child("userRole")无法正确获取字段值,需先遍历子节点或提取第一个匹配项。
  2. 空值判断顺序错误:先执行value.equals("Flood Victim")再判断value != null,会触发空指针异常,应先判断值不为null再做比较。
  3. 字段名不匹配:数据库中角色字段为role,但代码中使用userRole,导致无法获取正确值。
  4. 类名不一致:需求中Rescuer对应HomeRes.class,但代码里写的是homeRescuer.class,需保持类名统一。

修复后的代码

mAuth.signInWithEmailAndPassword(userEmail, userPswd)
    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task) {
            if (task.isSuccessful()) {
                Toast.makeText(LoginActivity.this, "登录成功!", Toast.LENGTH_SHORT).show();

                FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
                DatabaseReference reference = firebaseDatabase.getReference().child("User");

                // 根据userName(邮箱)查询用户信息
                reference.orderByChild("userName").equalTo(userEmail).addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        if (snapshot.exists()) {
                            Log.d("User exists", "Welcome!");
                            // 遍历查询到的用户节点(实际应只有一个匹配项)
                            for (DataSnapshot userSnapshot : snapshot.getChildren()) {
                                String role = userSnapshot.child("role").getValue(String.class);
                                // 先判断role不为null再进行比较
                                if (role != null) {
                                    if (role.equals("Flood Victim")) {
                                        startActivity(new Intent(LoginActivity.this, HomeActivity.class));
                                    } else if (role.equals("Rescuer")) {
                                        startActivity(new Intent(LoginActivity.this, HomeRes.class));
                                    } else if (role.equals("Admin")) {
                                        // 补充Admin对应的页面跳转,示例为AdminHomeActivity
                                        startActivity(new Intent(LoginActivity.this, AdminHomeActivity.class));
                                    } else {
                                        // 默认跳转页面
                                        startActivity(new Intent(LoginActivity.this, homeFv.class));
                                    }
                                    finish();
                                    break; // 找到匹配用户后跳出循环
                                }
                            }
                        } else {
                            Toast.makeText(LoginActivity.this, "未找到用户信息", Toast.LENGTH_SHORT).show();
                        }
                    }

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

            } else {
                Toast.makeText(LoginActivity.this, "登录失败: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
            }
        }
    });

额外优化建议

  • 用Auth UID查询(更高效):如果数据库用户节点的键是Firebase Auth生成的用户UID,可直接通过reference.child(mAuth.getCurrentUser().getUid())查询,无需orderByChild,性能更高。
  • 添加异常处理:在获取字段值时增加异常捕获,避免因数据格式不一致导致崩溃。
  • 统一类名规范:建议Activity类名采用大驼峰命名法(如HomeRescuerActivity),避免小写开头的类名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:15:33