Неожиданное поведение при запросе .whereArrayContains () - PullRequest
0 голосов
/ 24 ноября 2018

У меня есть RecyclerView, который использует FireaseUI и упорядочивает все объекты из узла «Опросы» по полю «отметка времени» (последовательно).

Новый фрагмент - .onViewCreated ()

 Query queryStore = FirebaseFirestore.getInstance()
            .collection(POLLS_LABEL)
            .orderBy("timestamp", Query.Direction.ASCENDING);
    //Cloud Firestore does not have any ordering; must implement a timestampe to order sequentially

    FirestoreRecyclerOptions<Poll> storeOptions = new FirestoreRecyclerOptions.Builder<Poll>()
            .setQuery(queryStore, Poll.class)
            .build();
    mFirestoreAdaper = new FirestoreRecyclerAdapter<Poll, PollHolder>(storeOptions) {
        @Override
        protected void onBindViewHolder(@NonNull final PollHolder holder, final int position, @NonNull Poll model) {
            holder.mPollQuestion.setText(model.getQuestion());
            String voteCount = String.valueOf(model.getVote_count());
            //TODO: Investigate formatting of vote count for thousands
            holder.mVoteCount.setText(voteCount);
            Picasso.get()
                    .load(model.getImage_URL())
                    .fit()
                    .into(holder.mPollImage);
            holder.mView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent toClickedPoll = new Intent(getActivity(), PollHostActivity.class);
                    String recyclerPosition = getSnapshots().getSnapshot(position).getId();
                    Log.v("Firestore ID", recyclerPosition);
                    toClickedPoll.putExtra("POLL_ID", recyclerPosition);
                    startActivity(toClickedPoll);

                }
            });
        }

У меня есть другой макет в моем приложении, который подписывается на этот же узел, но вместо этого запрашивает «последователи», а затем «timestamp.:

Следующий фрагмент - .onViewCreated ()

  Query queryStore = FirebaseFirestore.getInstance()
            .collection(POLLS_LABEL)
            .whereArrayContains("followers", mUserId)
            .orderBy("timestamp", Query.Direction.ASCENDING);

    FirestoreRecyclerOptions<Poll> storeOptions = new FirestoreRecyclerOptions.Builder<Poll>()
            .setQuery(queryStore, Poll.class)
            .build();
    mFirestoreAdaper = new FirestoreRecyclerAdapter<Poll, PollHolder>(storeOptions) {
        @Override
        protected void onBindViewHolder(@NonNull final PollHolder holder, final int position, @NonNull Poll model) {
            holder.mPollQuestion.setText(model.getQuestion());
            String voteCount = String.valueOf(model.getVote_count());
            //TODO: Investigate formatting of vote count for thousands
            holder.mVoteCount.setText(voteCount);
            Picasso.get()
                    .load(model.getImage_URL())
                    .fit()
                    .into(holder.mPollImage);
            holder.mView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent toClickedPoll = new Intent(getActivity(), PollHostActivity.class);
                    String recyclerPosition = getSnapshots().getSnapshot(position).getId();
                    Log.v("Firestore ID", recyclerPosition);
                    toClickedPoll.putExtra("POLL_ID", recyclerPosition);
                    startActivity(toClickedPoll);

                }
            });
        }

В первом сценарии элементы пользовательского интерфейса заполняются в реальном времени в моем RecyclerView по мере их добавления в Firebase. Однако, когда я запрашиваю ".whereArrayContains", я не получаю такого же поведения, и мне было любопытнопочему? Элементы появляются только после перезапуска приложения:

enter image description here

Редактировать:

Я прокомментировал следующую строку:

// .whereArrayContains ("последователи", mUserId)

и поведение, выполненное в соответствии с ожиданиями, поэтому я могу изолировать проблему в запросе .whereArrayContains (). Это единственное различие междукаждый фрагмент.

1 Ответ

0 голосов
/ 24 ноября 2018

Это происходит потому, что когда вы используете методы whereArrayContains() и orderBy() в одном запросе, требуется index .Чтобы использовать его, перейдите на Консоль Firebase и создайте его вручную, или, если вы используете Android Studio, вы увидите в своем журнале сообщений следующее сообщение:

W / Firestore: (0.6.6-dev) [Firestore]: Ошибка прослушивания запроса (продукты, в которых массив array_contains метка YourItem по метке времени): Status {code = FAILED_PRECONDITION, description = Для запроса требуется индекс.Вы можете создать его здесь: ...

Вы можете просто щелкнуть эту ссылку или скопировать и вставить URL-адрес в веб-браузер, и ваш индекс будет создан автоматически.

Зачем нужен этот индекс?

Как вы, наверное, заметили, запросы в Cloud Firestore очень быстрые, и это потому, что Firestore автоматически создает индексы для любых полей, которые есть в вашем документе.Когда вам нужно заказать ваши товары, требуется определенный индекс, который должен быть создан, как описано выше.Однако, если вы намерены создать индекс вручную, выберите также из раскрывающегося списка соответствующий параметр Array contains, как показано на рисунке ниже:

enter image description here

...