Получение данных из другого класса в одном запросе

Я создал приложение, которое использует Parse. Мое приложение позволяет пользователям регистрироваться, входить в систему, а затем публиковать в облачной базе данных.
У меня есть два класса Parse, один называется User, а другой - Posts. Пользователь состоит из ObjectId, имени пользователя и пароля, а сообщения состоит из ObjectId, текста и пользователя. Из которых пользователь является указателем на ObjectId в классе User.

Я создал метод в моем приложении под названием getData() который содержит ParseQuery, он запрашивает класс Posts, выбирает текстовое поле и включает в себя поле пользователя. Затем запрос извлекает данные в список, а затем перебирает каждую строку списка, собирает строку из текстового поля и затем добавляет ее в ListView на интерфейсе пользователя, используя postList.add(textList.get(i).getString("text")); каждый раз, когда программа проходит цикл.
Внутри цикла находится еще один запрос, который запрашивает класс User, выбирает поле objectId, затем я добавляю к запросу ограничение, чтобы он получал только те данные, у которых поле objectId равно полю пользователя в классе Posts (я думаю,).

ParseQuery<ParseObject> queryUser = ParseQuery.getQuery("User");
                        queryUser.selectKeys(Arrays.asList("objectId"));
                        queryUser.whereEqualTo("objectId", textList.get(i).getString("user"));

Затем я хочу взять собранные данные об имени пользователя, полученные из запроса, поместить их в строку и отобразить на экране в виде тоста. Так что в основном getData() Метод должен собрать все строки из текстового поля и имя пользователя, который его опубликовал.

Проблема в том, что я не уверен, что пытаюсь сделать это правильно. Мое приложение выдает ошибку, когда этот фрагмент кода выполняется, поэтому я, очевидно, что-то делаю не так.

java.lang.IllegalStateException: ParseObject has no data for this key.  Call fetchIfNeeded() to get the data.
            at com.parse.ParseObject.checkGetAccess(ParseObject.java:3235)
            at com.parse.ParseObject.getString(ParseObject.java:2817)
            at com.text.parse.MainActivity$3.done(MainActivity.java:186)

Код в строке 186: queryUser.whereEqualTo("objectId", textList.get(i).getString("user"));

Мои вопросы:
1. Я пытаюсь сделать это правильно?
2. Почему я получаю эту ошибку?

Код для getData() метод:

public void getData() {

        final ArrayList<String> postList = new ArrayList<String>();
        final ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(this, R.layout.listview_row, postList);


        final ParseQuery<ParseObject> queryPosts = ParseQuery.getQuery("Posts");
        queryPosts.selectKeys(Arrays.asList("text"));
        queryPosts.include("user");
        queryPosts.addDescendingOrder("createdAt");
        queryPosts.setLimit(20);

        queryPosts.findInBackground(new FindCallback<ParseObject>() {

            @Override
            public void done(List<ParseObject> textList, ParseException e) {

                if (e == null) {
                    //query successful

                    for (int i = 0; i < textList.size(); i++) {

                        postList.add(textList.get(i).getString("text"));

                        ParseQuery<ParseObject> queryUser = ParseQuery.getQuery("User");
                        queryUser.selectKeys(Arrays.asList("objectId"));
                        queryUser.whereEqualTo("objectId", textList.get(i).getString("user"));
                        queryUser.setLimit(20);

                        queryUser.findInBackground(new FindCallback<ParseObject>() {
                            @Override
                            public void done(List<ParseObject> userList, ParseException e) {

                                if (e == null) {

                                    String s = userList.get(0).getString("username").toString();

                                    Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
                                }

                                else {
                                    //query error

                                    Toast.makeText(MainActivity.this, "query error: " + e, Toast.LENGTH_LONG).show();
                                }
                            }
                        });
                    }

                    lvText.setAdapter(listAdapter);

                } else {
                    //query error

                    Toast.makeText(MainActivity.this, "query error: " + e, Toast.LENGTH_LONG).show();
                }

            }
        });
    }



Извините за длинный вопрос. Любая помощь будет принята с благодарностью, спасибо.


ОБНОВИТЬ:
Для тех, кто столкнулся с подобной проблемой, вот как я заставил его работать:

public void getData() {

    final ArrayList<String> postList = new ArrayList<String>();
    final ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(this, R.layout.listview_row, postList);


    final ParseQuery<ParseObject> queryPosts = ParseQuery.getQuery("Posts");
    queryPosts.include("user");
    queryPosts.addDescendingOrder("createdAt");
    queryPosts.setLimit(20);

    queryPosts.findInBackground(new FindCallback<ParseObject>() {

        @Override
        public void done(List<ParseObject> textList, ParseException e) {

            if (e == null) {
                //query successful

                for (int i = 0; i < textList.size(); i++) {

                    postList.add(textList.get(i).getString("text"));


                    ParseObject po1 = textList.get(i);
                    ParseObject po2 = po1.getParseObject("user");
                    String username = po2.getString("username");

                    Toast.makeText(MainActivity.this, username, Toast.LENGTH_SHORT).show();
                }

                lvText.setAdapter(listAdapter);

            } else {
                //query error

                Toast.makeText(MainActivity.this, "query error: " + e, Toast.LENGTH_LONG).show();
            }

        }
    });
}


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

1 ответ

Решение

Этот метод, как показано, не делает ничего полезного:

ParseQuery<ParseObject> queryUser = ParseQuery.getQuery("User");
queryUser.selectKeys(Arrays.asList("objectId"));
queryUser.whereEqualTo("objectId", textList.get(i).getString("user"));

selectKeys Заявление говорит, что нужно только вернуть содержимое objectId столбец, который вы передаете в whereEqualTo оператор в качестве параметра... кажется глупым запускать запрос, чтобы получить значение, которое у вас уже есть!?. Я бы не стал пользователем selectKeys пока вы не думаете, что вам нужно оптимизировать свои запросы. Единственное использование этого запроса - дать вам знать, если objectId действителен, так как запрос вернется null если это не является действительным objectId для User,

Я надеюсь, что вы хотите получить больше информации о пользователе, поэтому, если вы удалите selectKeys тогда другие столбцы будут возвращены.

Дело в том, что fetchIfNeeded вызывает исключение из-за этой строки:

queryUser.whereEqualTo("objectId", textList.get(i).getString("user"));

Это говорит о том, что textList.get(i).getString("user") не возвращает objectId для пользователя. Если вместо этого возвращается username как подсказывают некоторые другие ваши комментарии (не уверен здесь), вам нужно изменить эту строку кода следующим образом:

queryUser.whereEqualTo("username", textList.get(i).getString("user"));

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

Другие вопросы по тегам