Как использовать orderByChild или orderByValue в FirebaseRecyclerAdapter

Я ищу способ отсортировать мои данные в RecyclerView. В данный момент я использую для этого метод приоритета, но я знаю, что для этого лучше применить метод orderByChild или orderByValue. Я просто не могу найти, как это сделать правильно.

Моя (соответствующая) структура данных следующая (формат болта):

path /events/{event}/GeneralInfo is GeneralInfo{}
path /events/{event}/instances/{instance} is Instance{}

type GeneralInfo {
    owner : KeyString,
    name : ShortNameString | Null, 
    color : Number | Null,
    description : NoteString | Null,
    shared : Boolean | Null,
    startDate : DateString,
    endDate : DateString, 
    instances: Map<KeyString, Boolean>,
    logoAvailable : Boolean | Null
}

type Instance {
    eventKey : KeyString,
    startDateTime : DateString,
    endDateTime : DateString,
    note : String | Null,
}

type KeyString extends String {
    validate() { this.length > 0 && this.length <= 255 }
}

type DateString extends String {
    validate() { this.length == 12 }
}

type ShortNameString extends String {
    validate() { this.length >= 0 && this.length <= 32 }
}

В настоящее время FirebaseRecyclerAdapter инициализируется следующим образом:

Query q = getGeneralInfo( eventKey ).child( "instances" ).orderByPriority();

mAdapter = new FirebaseRecyclerAdapter<Boolean, InstanceViewHolder>(Boolean.class, R.layout.instance_card, InstanceViewHolder.class, q) {
    @Override
    protected void populateViewHolder(final InstanceViewHolder viewHolder, Boolean model, final int position) {
       getInstanceByKey(mEventKey, refKey).addListenerForSingleValueEvent(new ValueEventListener() {
          @Override
          public void onDataChange(DataSnapshot dataSnapshot) {
             Instance i = dataSnapshot.getValue(Instance.class);
             ....

Обратите внимание, что я использую ключевое поле индекса (поле с логическим значением) для извлечения фактических данных. Поле индекса в настоящее время отсортировано (с использованием приоритетов).

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

p.s. Хотя может показаться, что данные не нормализованы, это так: путь /events/{event} никогда не используется для извлечения данных. Это делается только для того, чтобы иметь некоторый обзор.


person Peter    schedule 18.09.2016    source источник
comment
Какое значение вы сейчас имеете в приоритете каждого экземпляра?   -  person Frank van Puffelen    schedule 19.09.2016
comment
Установлен приоритет: Double.parseDouble( i.getStartDateTime() );   -  person Peter    schedule 19.09.2016
comment
Тип DateString имеет формат: 201609191200 (19 сентября, 12:00).   -  person Peter    schedule 19.09.2016


Ответы (1)


Вам не нужны приоритеты, если у вас уже есть дочерний элемент со значением, которое вы хотите заказать. Из комментариев кажется, что ваш приоритет имеет то же значение, что и дата начала. В этом случае вы также можете заказать по этому свойству:

Query q = getGeneralInfo( eventKey ).child( "instances" ).orderByChild("startDate");

Вам нужно будет добавить индекс к экземплярам:

"instances": {
  ".indexOn": "startDate"
}

Обновить

Очевидно, вы загружаете /events/{event}/GeneralInfo/instances, который вы определили как instances: Map<KeyString, Boolean>.

Поскольку ясно, что вы хотите сохранить значение, я бы изменил его на Map<KeyString, Long>, а затем сохранил временную метку даты начала в качестве значения в индексе.

Затем вы можете загружать/фильтровать их в правильном порядке с помощью orderByValue().

person Frank van Puffelen    schedule 19.09.2016
comment
Привет, Фрэнк, спасибо за вашу реакцию. Это прекрасно работает в ситуациях, когда я пытаюсь получить список объектов напрямую через запрос. Но в этой ситуации я использую индексную карту. Запрос getGeneralInfo( eventKey ).child( "instances" ) возвращает путь path /events/{event}/GeneralInfo/instances типа Map<KeyString, Boolean>. Дочернего элемента «startDateTime» нет, и упорядочивание, похоже, не работает (работает при использовании запроса с полным путем: /events/{event}/instances/{instance}) - person Peter; 19.09.2016
comment
В моей структуре данных я использую множество индексных карт. Например, в ситуациях, когда другим пользователям предоставляется доступ только к части данных. Пример, чтобы придерживаться этой структуры данных: представьте, что у другого пользователя есть карта индекса только с подмножеством экземпляров в пути path /events/{event}/GeneralInfo/instances. Видите ли вы какое-либо решение для применения orderByChild() в этом случае, может быть, мне нужно использовать другую структуру данных, или я обязан использовать приоритеты в этих ситуациях? - person Peter; 19.09.2016
comment
Ах... В таком случае мне бы не помешал образец JSON. Я добавил обновление. - person Frank van Puffelen; 19.09.2016