Сбой Firebase LimitToLast при попытке загрузить новые данные - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь загрузить больше элементов после того, как мои 20 пользователей были опубликованы в моем ListView (эта функция работает нормально), но когда я прокручиваю до конца ListView, я хочу загрузить еще 20 пользователей, но происходит сбой.

Это то, что я сделал до сих пор

FilterData.class

private String oldestUserID;

private void fetchData(DataSnapshot dataSnapshot) {

    mList.clear();

    for (DataSnapshot snapshot : dataSnapshot.getChildren()) {

        oldestUserID = dataSnapshot.getKey();
        userPojo = snapshot.getValue(UserPojo.class);
        String email = userPojo.getEmail();
        mList.add(email);
    }
    fetchSuccessListener.onListFetched(true);
}

public void refillListView(ListView listView) {

    listView.setOnScrollListener(new AbsListView.OnScrollListener() {

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            currentScrollState = scrollState;
            isScrollCompleted();

        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                             int visibleItemCount, int totalItemCount) {
            currentFirstVisibleItem = firstVisibleItem;
            currentVisibleItemCount = visibleItemCount;
            totalItem = totalItemCount;

        }

        private void isScrollCompleted() {
            if (totalItem - currentFirstVisibleItem == currentVisibleItemCount
                    && currentScrollState == SCROLL_STATE_IDLE) {

                mDatabase.orderByKey().startAt(oldestUserID).limitToFirst(20).addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        fetchData(dataSnapshot);
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });
            }


        }


    });
}

Вот как это работает, я использую интерфейс, чтобы определить, когда мои данные заканчивают выборку, и уведомить мой адаптер о заполнении ListView, который работает нормально с моими первыми 20 пользователями, но когда я прокручиваю до конца, я хочу список для добавления новых пользователей (еще 20), но я получил этот крашлог

Невозможно вызвать limitToLast для запроса с ранее установленным пределом!

Теперь вот как я вызываю мои методы для получения данных

MainActivity.class

Интерфейс для заполнения списка при получении данных (работает нормально)

@Override
public void onListFetched(boolean fetched) {
    if(fetched){

        mUserListView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }
}

и это, чтобы просто знать, когда пользователь прокрутил и должен загрузить еще 20 пользователей

filterData.refillListView(mUserListView);

То, что я пытаюсь сделать выше, это получить последний идентификатор пользователя в моей базе данных, чтобы начать запрашивать 20 новых пользователей после последнего запроса, чтобы я мог загрузить еще 20.

Вот запрос, который я использую, чтобы получить первых 20 пользователей

 mRootDatabase = FirebaseDatabase.getInstance().getReference().child("Usuarios");
        query = mRootDatabase.limitToFirst(20);

Структура базы данных Firebase выглядит следующим образом

Firebase Database

Редактировать: ошибка Logcat указывает на эту строку

mDatabase.orderByKey().startAt(oldestUserID).limitToFirst(20).....

Спасибо за любую помощь!

Редактировать: фрагмент

public void refillListView() {
mQueryDatabase.orderByKey().startAt(oldestUserID).limitToFirst(20).addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            fetchData(dataSnapshot);
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });
}

где private Query mQueryDatabase; передается моим конструктором

public FilterData(Query mQueryDatabase, Context context) {
        this.mQueryDatabase = mQueryDatabase;
        this.userPojo = new UserPojo();
        this.mContext = context;
    }

и заполнено так

  Query query = mRootDatabase.limitToFirst(20);
       FilterData filterData  = new FilterData(query,this);

Старейший идентификатор пользователя извлекается из fetchData(dataSnapshot);

Где fetchData

private void fetchData(DataSnapshot dataSnapshot) {

        mList.clear();

        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {

            oldestUserID = snapshot.getKey();
            userPojo = snapshot.getValue(UserPojo.class);
            String email = userPojo.getEmail();
            mList.add(email);
        }
        fetchSuccessListener.onListFetched(true);
    }

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Здесь я сделал Firebase-Chat-Pagination. Сверьтесь с этим. Это может вам помочь.

private void loadDataFirst() {
    mUserRefValueEventListener = mConversationRef.child(mLocation)
            .limitToLast(TOTAL_ITEM_EACH_LOAD)
            .orderByKey()
            .addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    // It should be null when new meesage sent by own
                    mLastDataSnapshot = null;
                    if (dataSnapshot.exists()) {
                        mChatList.clear();
                        for (DataSnapshot readDataSnapshot : dataSnapshot.getChildren()) {
                            ChatResponse chatModel = readDataSnapshot.getValue(ChatResponse.class);
                            if (chatModel != null) {
                                mChatList.add(chatModel);
                            }
                            // We need First DataSnapshot for pagination
                            if (mLastDataSnapshot == null) {
                                mLastDataSnapshot = readDataSnapshot;
                            }

                        }
                        mView.onFetchMessagesSuccess(mChatList);
                    }
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });

}

 public void loadMoreDataPagination() {

    if (mLastDataSnapshot != null && (mTotalCount == 0 || mView.getChatMessageCount() < mTotalCount)) {
        mUserRefValueEventListener = mConversationRef.child(mLocation)
                .orderByKey()
                .endAt(mLastDataSnapshot.getKey())
                .limitToLast(TOTAL_ITEM_EACH_LOAD)
                .addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {


                        if (dataSnapshot.exists()) {
                            mChatList.clear();
                            for (DataSnapshot readDataSnapshot : dataSnapshot.getChildren()) {
                                ChatResponse chatModel = readDataSnapshot.getValue(ChatResponse.class);
                                if (chatModel != null) {
                                    mChatList.add(chatModel);
                                }
                                // We need Last DataSnapshot for pagination while load more
                                if (mChatList.size() == 1) {
                                    mLastDataSnapshot = readDataSnapshot;
                                }
                            }
                            // One item duplicates from last list so need to Remove it
                            mChatList.remove(mChatList.size() - 1);
                            mView.onFetchLoadMoreSuccess(mChatList, mTotalCount);

                        }
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {
                        mView.hideLoading();
                    }
                });
    }
}
0 голосов
/ 29 августа 2018

Насколько я понимаю, вы делаете это изначально:

Query query = mRootDatabase.limitToFirst(20);
FilterData filterData  = new FilterData(query,this);

И FilterData затем делает:

public FilterData(Query mQueryDatabase, Context context) {
    this.mQueryDatabase = mQueryDatabase;
    this.userPojo = new UserPojo();
    this.mContext = context;
}

А потом:

mQueryDatabase.orderByKey().startAt(oldestUserID).limitToFirst(20).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        fetchData(dataSnapshot);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        throw databaseError.toException(); // don't ignore errors
    }
});

На этом этапе, если мы объединяем все вместе, у вас есть:

mRootDatabase
  .limitToFirst(20)
  .orderByKey()
  .startAt(oldestUserID)
  .limitToFirst(20)
  .addListenerForSingleValueEvent(
    ...

И так как у вас есть limitToFirst(20) там дважды, это объясняет, почему вы получаете сообщение об ошибке.

У меня такое чувство, что вы хотите передать корневую ссылку для запроса в FilterData, поэтому:

FilterData filterData  = new FilterData(mRootDatabase,this);

Кроме того, вы можете создать базовый запрос (все части запроса, которые являются постоянными) вне FilterData:

Query query = mRootDatabase.orderByKey().limitToFirst(20);

А затем в FilterData вы добавляете только переменную часть (предложение startAt()):

mQueryDatabase.startAt(oldestUserID).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        fetchData(dataSnapshot);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        throw databaseError.toException(); // don't ignore errors
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...