Эффективное получение пользовательских данных из базы данных Firebase - PullRequest
0 голосов
/ 18 октября 2018

Я пытаюсь получить доступ к имени пользователя для отображения на экране, и я получаю имя пользователя из моей базы данных Firebase.

Код для получения имени пользователя довольно длинный,

myRef.addListenerForSingleValueEvent(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String userName = dataSnapshot.child("userName").getValue(String.class);
            navUsername.setText(userName);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });

Итак, я пытаюсь сделать так, чтобы этот бит кода возвращал строку с именем 'specUserName', чтобы я мог легко получить к ней доступ из любого класса без необходимости каждый раз вставлять эту длинную строку кода.В моем User.class я добавил это

    public String getUserName() {
    myRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            specUserName = dataSnapshot.child("userName").getValue(String.class);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });
    return specUserName;
}

И я пытаюсь получить это в моем HomePage.class, выполнив это

    users.getUserName();
    navUsername.setText(users.specUserName);

Но теперь HomePage продолжает падать всякий раз, когдаЯ открываю его, и это ошибка, которую я получаю в своем Logcat.

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.brent.fifty_fifty.User.getUserName()' on a null object reference
    at com.example.brent.fifty_fifty.HomePage.onCreateOptionsMenu(HomePage.java:84)

HomePage: 84 - это место, где я вызываю метод getUserName (), но он продолжает возвращать ноль и сбой.

Любая помощь?

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Это может произойти по разным причинам, и одна из них может заключаться в том, что myRef не дана правильная ссылка на вашу базу данных в вашем классе пользователя или по любой другой причине.

Однако проблема, с которой вам придется столкнутьсяполучить имя пользователя, может быть решено различными способами.

Во-первых, если вы используете электронную почту / пароль для регистрации пользователя, у вас уже есть имя пользователя user, которое они имеют в своем GoogleID.

Вы можете получить это username легко, просто с помощью этого кода:

FirebaseAuth mAuth = FirebaseAuth.getInstance();
String username = mAuth.getCurrentUser.getUsername();

Также легко передать ваши данные к следующему занятию, если у вас есть данные в одном занятии.Вы можете сделать это методом putExtra().

// to send data to MainActivity from the class where you first got username value

Intent intent = new Intent(getBaseContext(), MainActivity.class);
intent.putExtra("username", userName);
startActivity(intent);

// to recieve data in MainActivity

String uname = getIntent().getStringExtra("username");
0 голосов
/ 18 октября 2018

Данные загружаются из Firebase асинхронно.Поскольку вы не можете заставить getUserName ждать, пока данные станут доступны (это будет означать, что ваше приложение перестает отвечать на запросы), вы не сможете вернуть имя пользователя таким образом.

Чтобы понять, почему, поместите несколько операторов логирования, например, так:

System.out.println("Before attaching listener");
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        System.out.println("Got data");
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        throw databaseError.toException();
    }
});
System.out.println("After attaching listener");

Когда вы запускаете этот код, он печатает:

Перед подключением слушателя

После подключения слушателя

Получил данные

Это, вероятно, не то, что вы ожидали.Но это определенно объясняет, почему вы не можете вернуть имя пользователя.К тому времени, когда выполняется оператор return, данные еще не загружены, а onDataChange() еще не был вызван.

Для этого есть два распространенных решения:

  1. Переместите код, которому требуется имя пользователя, в метод getUserName.Это, безусловно, самое простое, но делает ваш метод getUserName менее пригодным для повторного использования.
  2. Создайте интерфейс обратного вызова, который вы передаете в getUserName и который вы затем вызываете, когда имя пользователя загружено.Это похоже на то, что ValueEventListener.onDataChange для самого Firebase, но в то же время зависит от логики вашего приложения.

Вместо показа кода для обоих здесь, я рекомендую вам проверить его в моем ответе здесь: Метод getContactsFromFirebase () возвращает пустой список

И чтобы показать, что вы не одиноки в борьбе с этим, вот несколько предыдущих вопросов по теме:

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