Firebase Android офлайн

При хранении около 5000 подустановок под одним узлом инициализация firebase становится очень медленной при использовании автономных возможностей. Это займет ~ 30 секунд до того, как будет выполнен первый запрос. После инициализации выполнение последующих запросов (например, перечисление первых 25 вспомогательных узлов) занимает менее секунды.

Для включения автономных возможностей я использую следующие свойства: Firebase.getDefaultConfig (). SetPersistenceEnabled (true); firebase.keepSynced (истина);

Моя структура выглядит так:

<root> |-my-app-name |-<uid> |-node |-sub node 1 |-... |-sub node 5000 

Сохранение синхронизации выполняется на узле <uid> . Суб-узлы представлены в представлении Recycler. Предпочтительно, я хотел бы перечислить все (вместо 25 на страницу), но я понимаю, что это невозможно, поскольку для работы с Firebase нет механизма курсора (как Android для SQLite).

Является ли это по дизайну и я пересматриваю свою структуру данных? Или я могу уменьшить время инициализации по-другому?

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

Благодаря! Нильс

 04-01 15:59:12.029 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 43005(1717KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 31MB/32MB, paused 5.674ms total 57.402ms 04-01 15:59:13.415 2222-2240/abcdef W/art: Suspending all threads took: 6.600ms 04-01 15:59:13.424 2222-2245/abcdef W/art: Suspending all threads took: 9.339ms 04-01 15:59:13.433 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 7097(281KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 32MB/32MB, paused 11.175ms total 27.105ms 04-01 15:59:13.821 2222-2245/abcdef I/art: Background partial concurrent mark sweep GC freed 101674(5MB) AllocSpace objects, 18(530KB) LOS objects, 35% free, 28MB/44MB, paused 3.400ms total 152.664ms 04-01 15:59:15.107 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 394024(15MB) AllocSpace objects, 0(0B) LOS objects, 20% free, 30MB/38MB, paused 1.865ms total 152.182ms 04-01 15:59:15.817 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 218328(8MB) AllocSpace objects, 0(0B) LOS objects, 19% free, 31MB/38MB, paused 1.711ms total 112.325ms 04-01 15:59:16.451 2222-2240/abcdef W/art: Suspending all threads took: 27.786ms 04-01 15:59:16.465 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 190591(7MB) AllocSpace objects, 0(0B) LOS objects, 18% free, 31MB/38MB, paused 1.832ms total 107.416ms 04-01 15:59:16.472 2222-2245/abcdef W/art: Suspending all threads took: 6.823ms 04-01 15:59:17.084 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 178714(6MB) AllocSpace objects, 0(0B) LOS objects, 15% free, 32MB/38MB, paused 1.717ms total 105.529ms 04-01 15:59:17.629 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 163584(6MB) AllocSpace objects, 0(0B) LOS objects, 14% free, 33MB/38MB, paused 1.743ms total 110.764ms 04-01 15:59:18.941 2222-2240/abcdef W/art: Suspending all threads took: 5.078ms 04-01 15:59:19.691 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 95627(3MB) AllocSpace objects, 0(0B) LOS objects, 8% free, 35MB/38MB, paused 7.190ms total 86.171ms 04-01 15:59:19.961 2222-2240/abcdef W/art: Suspending all threads took: 18.208ms 04-01 15:59:20.965 2222-2245/abcdef W/art: Suspending all threads took: 5.254ms 04-01 15:59:20.990 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 55899(2MB) AllocSpace objects, 0(0B) LOS objects, 5% free, 36MB/38MB, paused 6.799ms total 66.923ms 04-01 15:59:22.495 2222-2240/abcdef W/art: Suspending all threads took: 45.180ms 04-01 15:59:22.509 2222-2245/abcdef W/art: Suspending all threads took: 14.254ms 04-01 15:59:22.562 2222-2245/abcdef I/art: Background partial concurrent mark sweep GC freed 198174(6MB) AllocSpace objects, 3(487KB) LOS objects, 32% free, 33MB/49MB, paused 16.949ms total 215.369ms 04-01 15:59:23.811 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 392437(15MB) AllocSpace objects, 0(0B) LOS objects, 18% free, 35MB/43MB, paused 1.936ms total 168.222ms 04-01 15:59:24.480 2222-2240/abcdef W/art: Suspending all threads took: 22.464ms 04-01 15:59:24.497 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 227043(8MB) AllocSpace objects, 0(0B) LOS objects, 18% free, 35MB/43MB, paused 1.723ms total 117.855ms 04-01 15:59:25.173 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 203910(7MB) AllocSpace objects, 0(0B) LOS objects, 16% free, 36MB/43MB, paused 1.694ms total 112.618ms 04-01 15:59:25.181 2222-2245/abcdef W/art: Suspending all threads took: 7.301ms 04-01 15:59:25.784 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 185627(7MB) AllocSpace objects, 0(0B) LOS objects, 14% free, 37MB/43MB, paused 1.719ms total 115.362ms 04-01 15:59:26.345 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 167066(6MB) AllocSpace objects, 0(0B) LOS objects, 13% free, 37MB/43MB, paused 1.651ms total 106.055ms 04-01 15:59:26.865 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 154535(6MB) AllocSpace objects, 0(0B) LOS objects, 11% free, 38MB/43MB, paused 1.644ms total 104.888ms 04-01 15:59:28.357 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 151375(5MB) AllocSpace objects, 33(671KB) LOS objects, 9% free, 39MB/43MB, paused 2.740ms total 104.176ms 04-01 15:59:29.006 2222-2240/abcdef W/art: Suspending all threads took: 19.232ms 04-01 15:59:29.060 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 133554(5MB) AllocSpace objects, 29(580KB) LOS objects, 10% free, 39MB/43MB, paused 1.563ms total 100.220ms 04-01 15:59:30.173 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 131062(4MB) AllocSpace objects, 31(637KB) LOS objects, 9% free, 39MB/43MB, paused 1.653ms total 102.705ms 04-01 15:59:31.245 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 122085(4MB) AllocSpace objects, 26(522KB) LOS objects, 8% free, 39MB/43MB, paused 2.380ms total 100.776ms 04-01 15:59:32.024 2222-2240/abcdef W/art: Suspending all threads took: 20.662ms 

PS: Это перекрестная почта: https://groups.google.com/forum/#!topic/firebase-talk/migEAwv26ns

Solutions Collecting From Web of "Firebase Android офлайн"

Инициализация означает setValue для этого узла? Таким образом, инициализация 5000 суб-узлов под одним узлом, занимающим ~ 30 с, кажется мне очень необычной. Я работал с почти одинаковым размером данных в одном узле с гораздо более высокой производительностью. Поэтому я не уверен, сколько атрибутов вы используете под одним узлом, но в любом случае, я думаю, вам нужно снова проверить производительность. Я думаю, вы используете onCompleteListener для setValue для вычисления времени, затраченного на инициализацию данных, поскольку представление пользовательского интерфейса не дает вам точное время и часто медленнее, чем фактическое время работы.

Предпочтительно, я хотел бы перечислить все (вместо 25 на страницу), но я понимаю, что это невозможно, поскольку для работы с Firebase нет механизма курсора (как Android для SQLite).

Однако я не совсем уверен в вашей цели, но то, что я могу предложить для этих случаев, заключается в том, чтобы поддерживать базу данных Sqlite и Firebase. Позвольте пояснить.

Идея состоит в том, чтобы сохранить ту же копию базы данных Firebase для конкретного пользователя на телефоне пользователя. Так что локальная база данных может полностью использовать вашу цель, когда это необходимо. Вы можете запросить базу данных и использовать CursorLoader с которым вы CursorLoader небольшим опытом.

У него есть и другие преимущества. Вы можете обрабатывать автономную синхронизацию с помощью своего собственного механизма. Когда Интернет не работает, сохраните данные, которые вы хотите синхронизировать впоследствии, в локальной базе данных Sqlite, а затем, когда соединение будет завершено, вы получите обратный вызов в своем BroadcastReceiver . setValue вы можете легко setValue значение автономных данных в Firebase. Firebase делает это проще, но в любом случае, поскольку вы очень обеспокоены производительностью, вы можете попробовать.

Поведение GC, которое вы публикуете, обычно, когда ваше приложение делает слишком много работы. Firebase в основном использует WebSocket для поддержки подключения к удаленной базе данных. Поэтому я думаю, вам нужно проверить, не связаны ли вы с ненужными подключениями к базе данных Firebase. Попытайтесь использовать removeListener когда слушатели больше не нужны.

Означает ли Firebase всю базу данных при инициализации?

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

Таким образом, оштрафовать данные, так что один корневой узел содержит не более 200 вспомогательных узлов, кажется, сейчас является ответом. Я устанавливаю .keepSynced (true) на осколки, и это приводит к значительно лучшей производительности.

Чтобы представить перечеркнутый список в одном представлении recycler, я создал класс FirebaseArrays, который представляет собой коллекцию FirebaseArray, которая объединяет несколько массивов в одну наблюдаемую коллекцию.
https://gist.github.com/ndefeijter/2191f8a43ce903c5d9ea69f02c7ee7e9

Я также адаптировал FirebaseRecyclerAdapter для использования FirebaseArrays в качестве базовой структуры данных вместо одного FirebaseArray . Интерфейс расширен с использованием некоторых методов для добавления дополнительных путей Firebase (например, осколков).
https://gist.github.com/ndefeijter/d98eb5f643b5faf5476b8a611de912c1

Эти пути добавляются при событии «нагрузка больше» (например, в случае бесконечной прокрутки).

 private void loadMore() { final View view = getView(); if (null != view) { final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); final FirebaseRecyclerAdapter2<Visit, VisitViewHolder> adapter = (FirebaseRecyclerAdapter2<Visit, VisitViewHolder>) recyclerView.getAdapter(); adapter.addQuery(nextQuery()); } }