【问题标题】:Read from database while having two types of users在拥有两种类型的用户时从数据库中读取
【发布时间】:2019-04-17 08:41:59
【问题描述】:

我正在开发一些 android 应用程序,其中两种类型的用户可以登录,数据库将显示他们的信息。假设一种类型的用户是客户(“用户”),另一种是餐厅(“餐厅”)。当我尝试从数据库中读取用户详细信息时,问题就开始了。当我只有一种类型的用户(子“用户”)时,应用程序工作正常并显示用户信息,但是当我添加另一个用户(子“餐厅”)时,似乎应用程序不知道从哪个子用户登录在?希望这是有道理的:)

//JSON

{
  "Restaurants" : {
    "4kASMGuVlxgk8HiDsxEt7IcSo4y2" : {
      "restaurantEmail" : "res1@gmail.com",
      "restaurantName" : "res1",
      "restaurantPhone" : "123456"
    },
    "6FwZR8rYxyVKm8FC8v0jV4ZwgVs2" : {
      "restaurantEmail" : "1604@gmail.com",
      "restaurantName" : "restaurant1604",
      "restaurantPhone" : "123456"
    },
    "vERcsGqBA0VNDjXfNvrseA29UGc2" : {
      "restaurantEmail" : "restaurant3@gmail.com",
      "restaurantName" : "restaurant3",
      "restaurantPhone" : "123456"
    }
  },
  "Users" : {
    "3BCqSyocaScBiviSUf2QAXo5Fdu1" : {
      "phoneNumber" : "123456",
      "userEmail" : "test3@gmail.com",
      "userName" : "test3"
    },
    "wzz9NBQt2YfFikMHTaMIcdRyCRI2" : {
      "phoneNumber" : "123456",
      "userEmail" : "test5@gmail.com",
      "userName" : "test5"
    }
  }
}

//JAVA

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WelcomeActivity = new Intent(this,com.example.danie.dine.Activities.WelcomeActivity.class);
    BookingManagementActivity = new Intent(this,com.example.danie.dine.Activities.BookingManagementActivity.class);
    setContentView(R.layout.activity_home);

    mAuth = FirebaseAuth.getInstance();
    FirebaseUser currentUser = mAuth.getCurrentUser();
    userID = currentUser.getUid();
    mDatabase = FirebaseDatabase.getInstance();
    mRef = mDatabase.getReference("Users");

    mAuthListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
            FirebaseUser user = firebaseAuth.getCurrentUser();
            if (user != null) {
                // User is signed in

                showMessage("Successfully signed in with: " + user.getEmail());
            } else {
                // User is signed out
                showMessage("Successfully signed out.");
            }
            // ...
        }
    };

//添加缺失的部分代码

mRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            showInfo(dataSnapshot);
        }

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

        }
    });

// JAVA 试图从 DB 中读取 - 不工作

private void showInfo(DataSnapshot dataSnapshot) {
    for(DataSnapshot ds : dataSnapshot.getChildren()){
        UserInformation uInfo = new UserInformation();
        uInfo.setUserName(ds.child(userID).getValue(UserInformation.class).getUserName()); //get username
        uInfo.setUserEmail(ds.child(userID).getValue(UserInformation.class).getUserEmail()); //get user email
        uInfo.setPhoneNumber(ds.child(userID).getValue(UserInformation.class).getPhoneNumber()); //get user phone number
        //display user details
        lblUserName.setText(uInfo.getUserName()); //error points here
        lblUserEmail.setText(uInfo.getUserEmail());
        lblUserPhone.setText(uInfo.getPhoneNumber());
    }
}

//缺少部分代码#2

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

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

//JAVA用户信息对象

public class UserInformation {

private String userName;
private String phoneNumber;
private String userEmail;


public UserInformation(){
}


public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public String getPhoneNumber() {
    return phoneNumber;
}

public void setPhoneNumber(String phoneNumber) {
    this.phoneNumber = phoneNumber;
}

public String getUserEmail() {
    return userEmail;
}

public void setUserEmail(String userEmail) {
    this.userEmail = userEmail;
}

public UserInformation(String userName, String phoneNumber, String userEmail) {
    this.userName = userName;
    this.phoneNumber = phoneNumber;
    this.userEmail = userEmail;
}

}

到目前为止,我所尝试的,如果我只有一个孩子“用户”,应用程序从数据库中读取和显示没有任何问题,一旦我添加孩子“餐厅”,一切都变得香蕉......我认为我需要以某种方式指出代码仅读取子“用户”,因为我试图仅显示用户信息,而不是“餐厅”?

//错误信息

2019-04-17 11:44:33.116 11557-11557/com.example.danie.dine E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.danie.dine, PID: 11557
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.danie.dine.Model.UserInformation.getUserName()' on a null object reference
    at com.example.danie.dine.Activities.HomeActivity.showInfo(HomeActivity.java:172)
    at com.example.danie.dine.Activities.HomeActivity.access$100(HomeActivity.java:30)
    at com.example.danie.dine.Activities.HomeActivity$2.onDataChange(HomeActivity.java:93)
    at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@16.0.5:75)
    at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@16.0.5:63)
    at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@16.0.5:55)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

//建议修复

mRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            UserInformation userDetails = dataSnapshot.getValue(UserInformation.class);
            userDetails.getUserName();
            userDetails.getPhoneNumber();
            userDetails.getUserEmail();
            userDetails.setUserName(dataSnapshot.child(userID).getValue(UserInformation.class).getUserName()); //get username
            userDetails.setUserEmail(dataSnapshot.child(userID).getValue(UserInformation.class).getUserEmail()); //get user email
            userDetails.setPhoneNumber(dataSnapshot.child(userID).getValue(UserInformation.class).getPhoneNumber()); //get user phone number
            lblUserName.setText(userDetails.getUserName());
            lblUserEmail.setText(userDetails.getUserEmail());
            lblUserPhone.setText(userDetails.getPhoneNumber());

【问题讨论】:

  • 请添加您用于从数据库中获取数据的整个代码/
  • 您是否在调用查询或侦听器之前设置了数据库引用?从您发布的代码中我只能看到 mRef = mDatabase.getReference();如果这样留下会导致问题。
  • 嗨@Alex Mamo,抱歉,添加了部分代码。谢谢!
  • @DanielCzajka 你的mRef不应该被定义为:mDatabase.getReference().child("Users")吗?请回复@AlexMamo
  • 嗨,Mena,我猜这也可能是我的问题的根源。我刚刚尝试添加 mRef=mDatabase.getReference().child("Users");但仍然没有播放...... @AlexMamo,刚刚尝试过,同样的事情......它给了我 java.lang.NullPointerException 因为它无法从 db 读取信息......

标签: android firebase-realtime-database firebase-authentication


【解决方案1】:

保持简短

您必须创建两个方法:一个 getUser() 和另一个 getRestaurant(),因为您提供的数据库有两个根节点:用户和餐厅。

另一方面,如果您将所有用户(即用户和餐厅)保留在一个列表中,并带有一个附加类型属性(type:0 用于用户,type:1 用于餐厅,或 type:user 和 type:restaurant)单个数据库参考就足够了。您所要做的就是创建应扩展 UserModel 和 RestaurantModel 的 BaseModel,并在阅读 type 之后创建 User 或 Restaurant。

我希望这能回答你的问题。

【讨论】:

  • 嗨@Variag,感谢您的回复。现在我正在尝试仅从用户子级读取信息(showInfo() 方法)。即使我这样做 mRef = mDatabase.getReference().child("Users");它仍然不只从“用户”孩子那里阅读,我不知道为什么......
  • @AlexMamo 只是仔细检查了它,是的,那是代码错误指向的行。基本上这三个(getUserName、getUserEmail、getUserPhone)似乎都没有工作,我正在一个一个地评论它们并且总是首先没有被注释掉是给出一个错误......
  • @DanielCzajka 发送到showInfo() 之前的dataSnapshot 方法不为空吗?值是否添加到对象uInfo?值是否正确?
【解决方案2】:

非常感谢您的所有建议,我参考了 firebase 文档并从头开始重做所有从数据库函数读取的操作。似乎我的 userInfo() 方法不起作用,我摆脱了它并创建了新的(在 //proposal fix 注释下添加的代码。我希望有人会觉得它有用。吸取的教训:)

【讨论】:

    猜你喜欢
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 1970-01-01
    • 2015-02-27
    • 2012-08-31
    • 2011-10-17
    • 1970-01-01
    相关资源
    最近更新 更多