Получение "попытки вызвать виртуальный метод" java.lang.String java.lang.String.trim ()" для нулевой ссылки на объект", даже если ссылка не является нулевой

Я использую FirebaseUI в своем приложении и FirebaseRecyclerAdapter, чтобы быть более конкретным.

Я извлекаю данные из своей ссылки FirebaseDatabase, используя метод, указанный здесь.

Вот мой код:

private void attachRecyclerViewAdapter() {
        Query lastFifty = mDatabase.child(rID).limitToFirst(50);
        mRecyclerViewAdapter = new FirebaseRecyclerAdapter<AModelClass, AModelClass.ViewHolder>(
                AModelClass.class, R.layout.a_player_layout, APlayersModelClass.ViewHolder.class, lastFifty) {

            @Override
            protected void populateViewHolder(AModelClass.ViewHolder viewHolder, AsModelClass model, int position) {

                String key = this.getRef(position).getKey();
                aReference.child(requestID).child(key).addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        if (dataSnapshot.getValue() != null) {

                            Map<String, String> map = (Map<String, String>) dataSnapshot.getValue();
                            pA = map.get("pName");
                            uA = map.get("pUrl"); 
                            // error on line below
                            String cLatS = map.get("cLat").trim();
                            currentLtAU = Double.parseDouble(cLatS);
                            String cLngS = map.get("cLng").trim();
                            currentLnAU = Double.parseDouble(cLngS);

                            viewHolder.setPName(pA);
                            viewHolder.setPUrl(uA);
                            viewHolder.setCurrentLatAU(String.valueOf(currentLtAU));
                            viewHolder.setCurrentLngAU(String.valueOf(currentLnAU));

                        } else {
                            Snackbar snackbar = Snackbar
                                    .make(coordinatorLayout, "Some error occurred. Please retry!", Snackbar.LENGTH_SHORT);
                            snackbar.show();
                            onBackPressed();
                        }
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });

            }
        };

        aList.setAdapter(mRecyclerViewAdapter);
    }

Вот как выглядит структура базы данных:

-app
  -requestID
    -uniqueKey1
      -key: value
      -key: value
      -cLat: value
    -uniqueKey2
      -key: value
      -key: value
      -cLat: value

Как вы можете видеть в приведенной выше структуре базы данных, ссылка имеет 2 keys, и все данные извлекаются и отображаются в RecyclerView, но как только один ключ удаляется из ссылки, приложение вылетает, выдавая эту ошибку: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference в указанной строке выше.

Ссылка имеет один key кадр, и все те же поля, которые я извлекаю, также находятся в этом ключе. Тогда почему я получаю эту ошибку?


person Hammad Nasir    schedule 29.01.2017    source источник
comment
Почему вы используете Hashmap, а не AModelClass?   -  person OneCricketeer    schedule 29.01.2017
comment
@cricket_007 как я могу использовать AModelClass? Пожалуйста, дай мне знать.   -  person Hammad Nasir    schedule 29.01.2017
comment
Я не знаю, как выглядит ваш класс модели, но вы используете Firebase-ui, чтобы указать класс модели для вашего адаптера, но вы никогда его не используете... dataSnapshot.getValue принимает параметр класса, ИЛИ вы можете использовать этот AsModelClass model параметр, я думаю   -  person OneCricketeer    schedule 29.01.2017
comment
@cricket_007 эй, эй... можешь написать небольшой пример? Я немного смущен здесь. Пожалуйста?   -  person Hammad Nasir    schedule 29.01.2017
comment
Как я уже сказал, посмотрите на параметры populateViewHolder. У тебя там модель. Почему бы не использовать его?   -  person OneCricketeer    schedule 29.01.2017
comment
@ cricket_007 Да, я понял вашу точку зрения ... раньше этого не делал, поэтому прошу пример. Пожалуйста...   -  person Hammad Nasir    schedule 29.01.2017
comment
Я не знаю, что ты хочешь увидеть... model.getcLat()??   -  person OneCricketeer    schedule 29.01.2017
comment
@cricket_007 Кажется, у меня проблема... в том, что как только я удаляю ключ и значение внутри него, он не удаляется полностью, и код под populateViewHolder вызывается с частично удаленным значением, и, таким образом, это ошибка. Итак, как я могу полностью удалить его до того, как будет вызван код под populateViewHolder? и он должен вызываться только с оставшимися key(ами).   -  person Hammad Nasir    schedule 29.01.2017
comment
@cricket_007 здесь: stackoverflow.com/q/41925181/6144372 Я задал новый вопрос, основанный на проблеме, которую я выяснил. Пожалуйста, взгляните.   -  person Hammad Nasir    schedule 29.01.2017
comment
Я не очень хорошо разбираюсь в firebase api, но я думаю, что вы не должны помещать асинхронный new ValueEventListener внутрь метода, который существует только для заполнения держателя представления предоставленным параметром model, который является синхронным методом.   -  person OneCricketeer    schedule 29.01.2017
comment
@cricket_007 cricket_007 Я не делал этого раньше, но это был единственный способ, поскольку использование ValueEventListener до того, как возникла проблема с методом populateViewHolder(): stackoverflow.com /q/41910271/6144372 затем я провел небольшое исследование и нашел ответ: stackoverflow.com/a/36236657/6144372 которому я следую сейчас.   -  person Hammad Nasir    schedule 30.01.2017


Ответы (1)


Если это вызывает ошибку:

Map<String, String> map = (Map<String, String>) dataSnapshot.getValue();
String cLatS = map.get("cLat").trim();

Причина, скорее всего, в том, что у dataSnapshot нет ребенка cLat.

Вы должны проверить с помощью .hasChild("cLat") - см. Снимок данных

... или предотвратить попытку .trim(null) аналогично:

if(map.get("cLat") != null) {
    String cLatS = map.get("cLat").trim();
    currentLtAU = Double.parseDouble(cLatS);
}

В то время как для такого рода приложений вы можете проверить Firebase GeoFire.

person Martin Zeitler    schedule 29.01.2017
comment
см. обновленный вопрос. Я добавил структуру базы данных. - person Hammad Nasir; 29.01.2017
comment
Я выяснил, что вызывает эту ошибку, и разместил здесь новый вопрос, основанный на этой проблеме: stackoverflow.com/q/41925181/6144372 Пожалуйста, помогите с этим. Спасибо! - person Hammad Nasir; 29.01.2017
comment
@HammadNasir, тем не менее, я ответил на этот вопрос; поэтому этот ответ должен быть принят. - person Martin Zeitler; 30.01.2017