Чтение из базы данных при наличии двух типов пользователей - PullRequest
0 голосов
/ 17 апреля 2019

Я работаю над некоторым приложением для 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 для попытки чтения из БД - не работает

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 userInfo

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());

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

Большое спасибо за все ваши советы, я сослался на документацию Firebase и переделал все функции чтения из базы данных с нуля.Похоже, что мой метод userInfo () не работал, я избавился от него и создал новый (код добавлен под комментарием // предложения по исправлению. Я надеюсь, что кто-то сочтет его полезным. Урок выучен:)

0 голосов
/ 17 апреля 2019

Для краткости

Вам необходимо создать два метода: один getUser() и другой getRestaurant(), поскольку база данных, как вы ее представили, имеет два корневых узла: пользователи и рестораны.

Если, с другой стороны, вы держали всех пользователей (то есть «Пользователи и рестораны») в одном списке с дополнительным атрибутом типа (type:0 для пользователя и type:1 для ресторана или type:user и type:restaurant) одного Ссылка на базу данных будет достаточно. Все, что вам нужно сделать, это создать BaseModel, которую UserModel и RestaurantModel должны расширять, и после прочтения type вы создадите User или Restaurant.

Надеюсь, это ответит на ваш вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...