Прослушиватель Firebase .on() вызывает сбой приложения Cordova iOS

#ios #cordova #firebase #firebase-realtime-database

#iOS #cordova #firebase #firebase-realtime-database

Вопрос:

Я создал пустое, совершенно новое приложение Cordova (-v 6.3.1), созданное для iOS. Приложение ничего не делает, кроме следующего:

 var ref = new Firebase('url-to-firebase-leaf-node-with-4000-children');
ref.on("child_added", function(child, prev) {
    console.log("here");
});
  

Развертывание на iPhone. Приложение выходит из строя, и Xcode приводит следующее:

WebThread (7): EXC_BAD_ACCESS (code=1, address=0xbbadbeef) внутри bmalloc::VMHeap::grow() .

Если я сделаю это скорее:

var ref = new Firebase('url-to-firebase-leaf-node-with-100-children'); тогда приложение не вылетает.

Это явно проблема с памятью, но как ее можно решить? Поскольку 1,5 Мб данных извлекается из 4000 дочерних узлов, я бы не подумал, что это должно использовать всю доступную память. Пожалуйста, избегайте предложений не извлекать все данные — приложению нужны все данные, и оно отлично работает на Android.

Комментарии:

1. Я также должен отметить, что я использую Firebase 2.4.2.

2. Также следует отметить, что общий размер данных, извлекаемых из Firebase, составляет 1,5 Мб.

3. Обновление: я также пытался использовать WKWebView, но это тоже сбой.

Ответ №1:

Собственный сбой довольно выразителен. Приложению не хватает памяти.

Firebase SDK создает зеркало базы данных в памяти, используя ваши подписки. Даже если ваш child_added обратный вызов ничего не делает с дочерними снимками, это внутреннее дерево использует память для всех данных под узлом.

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

Комментарии:

1. Спасибо за ответ @vzsg. Проблема в том, что моему приложению нужны все 4000 дочерних узлов, и это отлично работает на Android. Я попытался выполнить разбиение данных на страницы, используя обещания по 50 дочерних узлов для каждого и используя .once('value') для каждой страницы по 50 узлов. На самом деле это работает для получения данных один раз, но после этого мне нужно прослушать изменения. Поэтому, если я попытаюсь добавить .on потом, он снова выйдет из строя.

2. Или нет способа разрешить приложению использовать больше памяти? Я тестировал это на iPhone 6s, и он выходит из строя, но у этого устройства больше памяти, чем у некоторых устройств Android, которые я тестировал, и которые работают нормально.

3. Кроме того, является ли исключение памяти результатом количества дочерних узлов или общего объема данных , хранящихся в дочерних узлах? т. Е. Будет ли сбой одного дочернего узла с 2 МБ данных таким же, как у 4000 дочерних узлов, содержащих в общей сложности 2 МБ данных?

4. На дочерний узел приходится накладные расходы, но я думаю, что общие данные имеют большее значение. (Это всего лишь мнение, поскольку у меня также нет понимания внутренних компонентов.) Возможно, вы могли бы попробовать использовать WKWebView вместо UIWebView, если вы еще не переключились?

5. Кажется, WKWebView был бы лучшим вариантом, но, похоже, нет никаких жизнеспособных вариантов. CrossWalk не для iOS, плагин Telerik WKWebView работает только на старой Cordova, а плагин Apache WKWebView Engine, похоже, не позволяет мне подключаться к Firebase. Знаете ли вы, как я мог бы реализовать WKWebView?

Ответ №2:

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