База данных Firebase: Исключение нехватки памяти при запросе огромного количества данных в приложении Android - PullRequest
0 голосов
/ 03 июля 2018

Я использую базу данных Firebase для своего приложения для Android. Мне нужен был уникальный 5-значный код, который должен быть действителен в течение 3 дней. Чтобы решить эту проблему, я вставил все возможные 5-значные коды в базу данных Firebase, где каждая запись изначально имеет статус 1. Итак, структура выглядит примерно так:

codes: {
  'abcde': {status:1},
  'zhghs': {status:1}
  .....
}

Этот codes объект имеет около 5 миллионов записей. Я думал, что установлю статус на 2, как только код будет использован.

Я использую это, чтобы получить код из Firebase:

db.getReference("codes")
                .orderByChild("status")
                .limitToFirst(1)
                .addListenerForSingleValueEvent { ..... }

Мне просто нужен 1 код, который имеет статус 1. Приведенный выше код вызывает OutOfMemoryException, поэтому я думаю, что он пытается загрузить все данные на устройство. Разве он не должен просто загружать один элемент на стороне устройства из-за ограничения limitToFirst(1)?

P.S. Я попробовал свои силы в Firebase FireStore. На данный момент он не позволяет импортировать огромные данные JSON без превышения ежедневных лимитов в 20 КБ.

Редактировать - я даже установил db.setPersistenceEnabled(false) Точная ошибка:

База данных Firebase обнаружила ошибку OutOfMemoryError. Вам может понадобиться уменьшите объем данных, которые вы синхронизируете с клиентом. java.lang.OutOfMemoryError: не удалось выделить 28701016 байт распределение с 16777216 свободных байтов и 18 МБ до OOM

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Звучит так, как будто у вас не определен индекс для вашего свойства status. В этом случае сервер не может выполнить заказ / фильтрацию за вас, и это будет сделано на клиенте. Это означает, что клиент должен прочитать все данные и сохранить их в памяти, объясняя огромное использование памяти.

Решение довольно простое: определите индекс для вашего свойства status.

{
  "rules": {
    "codes": {
      ".indexOn": "status"
    }
  }
}

Также см. Документацию по индексированию данных .

0 голосов
/ 04 июля 2018

Мне просто нужен 1 код со статусом 1.

В этом случае измените ваш запрос на:

db.getReference("codes")
            .orderByChild("status")
            .equalsTo(1)
            .limitToFirst(1)
            .addListenerForSingleValueEvent { ..... }

Даже с этим ограничением вы должны уменьшить объем данных, которые вы загружаете в память, потому что кажется, что вы вводите слишком много данных в память. В качестве альтернативы вы можете установить большой размер кучи, установив android:largeHeap="true" в файле Manifest.xml. Обычно эта ошибка исчезает.

Вы также можете взглянуть на обсуждение в этой тесно связанной статье здесь .

Как сказал @DougStevenson, на самом деле не является рекомендуемым способом решения ошибок OOM, но, как я видел в ответе @FrankvanPuffelen, ключом к решению проблемы является добавление ".indexOn": "status", которое изначально отсутствовало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...