2016-09-20 6 views
1

Запрос можно использовать для фильтрации больших предметов до меньшего числа, подходящего для синхронизации с клиентом.
Pagination также служит той же цели, то есть ограничить предметы меньшими числами, подходящими для клиента.Firebase Combining Query and Pagination

Рассмотрим следующую схему базы данных:

"users": { 
    "-KRyXWjI0X6UvffIB_Gc": { 
     "active": true, 
     "name": "John Doe", 
     "occupation": "Looking for firebase answer" 
    }, 
    "-KRyXBWwaK112OWGw5fa": { 
     "active": false, 
     "name": "Jane Doe", 
     "occupation": "Still stuck on combining query and pagination" 
    }, 
    "-KRyWfOg7Nj59qtoCG30": { 
     "active": true, 
     "name": "Johnnie Doe", 
     "occupation": "There is no greater sorrow than to recall in misery the time when we were stuck" 
    } 
} 

Если бы я, чтобы все активные пользователи, это будет выглядеть следующим образом: (код в Swift)

let usersRef = ref.child("users"); 
let query = usersRef.queryOrderedByChild("active") 
        .queryEqualToValue(true) 

После этого фильтра, его оставил меня с 10 000 пользователей. Извлечение всех этих пользователей в одно и то же время не может быть и речи. Он должен быть разбит на страницы.

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

let usersRef = ref.child("users"); 
let query = usersRef.queryOrderedByChild("active") 
        .queryEqualToValue(true) 

let usersPerPage = 10; 
query.queryOrderedByKey() 
    .queryStartingAtValue(lastKey) 
    .queryLimitedToFirst(usersPerPage) 

Это не будет работать, потому что:

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

После того, как я потратил 2 дня на размышление о том, как я должен решить эту ситуацию, я могу только придумать это решение «против лучшей практики».

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

"users": { 
    "-KRyXWjI0X6UvffIB_Gc": { 
     "key_active": "-KRyXWjI0X6UvffIB_Gc true" 
     "active": true, 
     "name": "John Doe", 
     "occupation": "Looking for firebase answer" 
    } 
} 

Теперь я мог сделать и разбиение на страницы и запрос с использованием одного OrderBy:

let usersPerPage = 10; 
query.queryOrderedByChild("key_active") 
    .queryStartingAtValue("\(lastKey) true") 
    .queryLimitedToFirst(usersPerPage) 

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

+0

Итак, в основном вы хотите получить только 10 пользователей за раз? – Dravidian

+0

10 активных пользователей одновременно. Да, это правильно. –

ответ

0

Просто добавьте это к вашему JSON дереву: -

active_Users :{ 
     uid1 : { 
      index : 1, 
      name : "John Doe" 
       }, 
     uid2 : { 
      index : 2, 
      name : "Johnnie Doe" 
     } 
} 

После этого просто следуйте этому ответу: - Retrieving 5 user's at a time, изменять его в соответствии с вашими требованиями.

Примечание: - Общее количество пользователей/должностей в этих ответах восстанавливается путем подсчета количества детей. Учитывая вашу тяжелую базу данных, вы можете захотеть сохранить totalNoOfUser в отдельном узле и увеличивать его каждый раз при добавлении нового пользователя.

+0

Пожалуйста, внимательно прочитайте вопрос.Он должен только возвращать активных пользователей. Кроме того, инкрементный индекс не очень хорош. Данные в db, возможно, изменились к тому моменту, когда клиентский успех увеличит индекс из-за латентности клиента, отличается от клиента. Это создаст проблему с новыми данными, которые станут старше старых. Это старый подход SQL для сохранения идентификатора. Поскольку мы используем DB типа типа JSON, лучше использовать алфавитный ключ, созданный из метки времени и некоторого случайного числа (базовый 64-кодированный), и эта функциональность уже поддерживается в Firebase (сам ключ). –

+0

Вы понимаете, что 'active_Users' - это совершенно другой узел, в котором вы будете добавлять или удалять uid, когда этот uid переключается между активным или неактивным режимом. – Dravidian

+0

Для данных, которые можно изменить, вы можете использовать транзакции в облачных функциях: https://firebase.google.com/docs/database/admin/save-data#section-transactions – Diego