Я учусь на инженера в университете, и мой проект заключается в создании приложения. Это почти закончено, но я должен оптимизировать стоимость данных, и я могу сказать вам, что мое приложение никогда не будет онлайн с такими затратами ...
Вот контекст:
- Я использую базу данных Firebase в реальном времени
- У меня включена постоянство
Столкнувшись с чрезвычайно высокими данными, загруженными из базы данных, по сравнению с ее размером, я решил попробовать кое-что проверить, откуда это взялось.
Я просто использовал цикл for и зацикливал примерно 850 раз одни и те же вещи.
Вот структура json того, что я скачал:
Это около 80 символов, если 1 символ равен 2 октекам, мы получили 2 * 80 * 850 = 136 000 октанов = 0,136 МО
Угадай, что? После этой загрузки загруженные данные выросли на 9,2 МО !!! что в 68 раз больше !!!
И размер базы данных составляет 60, поэтому я действительно не понимаю!
Вот код, который я использовал:
Это деятельность
ChildEventListener ItemsListener = new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) /**** HERE IS THE PROBLEM***/
{
if (dataSnapshot.exists())
{
DisplayItems(dataSnapshot);
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s)
{
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_items);
InitializeFields();
retrievedata();
}
public void AddToList(String articlename)
{
String messageKey = FirstRef.push().getKey(); //get a key
HashMap<String, Object> groupMessageKey = new HashMap<>();
String keyEvent = obj.getsEventID();
SecondRef = FirstRef.child(keyEvent).child(messageKey); // create reference
HashMap<String, Object> ArticleInfoMap = new HashMap<>();
ArticleInfoMap.put("Article", articlename); //put all article into map
ArticleInfoMap.put("Key", messageKey);
ArticleInfoMap.put("Check", false);
ArticleInfoMap.put("Name", currentUserName);
SecondRef.updateChildren(ArticleInfoMap); //add the object to the database
HashMap<String, Object> messageSendNotifications = new HashMap<>(); // message to send notifications to the members of the group
messageSendNotifications.put("from", currentUserID);
messageSendNotifications.put("message", obj.getsEventName());
messageSendNotifications.put("type", "AddGroup");
messageSendNotifications.put("zelement", articlename);
messageSendNotifications.put("zgroup", obj.getsGroupName());
SendNotifRef.child(obj.getsGroupID()).push().updateChildren(messageSendNotifications); //add the notificiations to the DB which is treated by cloud function
}
public void retrievedata(){
FirstRef.child(obj.getsEventID()).addChildEventListener(ItemsListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
FirstRef.child(obj.getsEventID()).removeEventListener(ItemsListener);
}
И я только что зациклился в onCreate:
for (int i=0; i<850;i++)
{
AddToList("Test" + i);
}
Итак, я действительно могу задать этот вопрос, они загружают вещи, о которых вы не знаете, и затем заставляют вас платить за это?
Это действительно проблема для меня. Каждый день я отправляю около 20 сообщений и легко получаю 2 / 3MB загруженных данных.
Это означает, что в день 400 пользователей будут стоить 1 доллар. Это очень дорого для бесплатного приложения.
Вот причина, по которой я могу думать о :
- Firebase использует очень большой ключ хеша, чтобы проверить, изменились ли данные и при каждом
назовите его, чтобы загрузить этот огромный ключ, и, наконец, ключ в 100 раз больше реальных данных, которые я хочу загрузить
Из чего не может прийти :
- Я уверен, что данные не загружаются снова, а не вызываются из памяти диска
=> потому что даже я загружал данные только 2 раза, и это стоило бы мне максимум 2 * 0,136 Mo, но это 9Mo.
Плюс я проверил в Tool => Device File Explorer, и я вижу базу данных, которая там хранится.
(по какой-то причине все уведомления также хранятся там, даже если я отправляю их только в базу данных)
Плюс, диск памяти только 549ko (что уже слишком много, потому что DB 60ko), так что это очень странно. Обратите внимание, что после 2/3 дней использования (только отправка реальных 50ko) объем памяти диска увеличивается до 6 / 7MB без причины
Ну, я надеюсь, что Firebase может решить эту проблему.
РЕДАКТИРОВАТЬ
Также странно, что я загружаю все это с моего телефона. Так что его даже не нужно загружать, а непосредственно хранить в памяти диска.
РЕДАКТИРОВАТЬ 2
1) Я использовал это видео для проверки пропускной способности: https://www.youtube.com/watch?v=9CObBsjk6Tc
Я переделал ту же операцию (на этот раз зациклил 100 раз те же данные)
for (int i=0; i<100;i++)
{
AddToList("Test");
}
Я только загрузил данные, но все равно он говорит мне, что я скачал 54,90 кБ + 42,60 кБ. ММХ ...
2) Хорошо, теперь давайте проведем еще один эксперимент: давайте очистим все данные, удалим цикл, так что теперь устройство должно будет загрузить все данные из firebase и посмотреть ...:
Потребовалось всего 10ko загрузки ... и я загрузил 4.10ko данных в "Список элементов" в соответствии с базой данных, так что различия должны исходить от некоторых хэш-ключей или чего-то еще, но это не большая разница.
3) Итак, давайте попробуем что-нибудь еще! Он снова ставит цикл, удаляет все данные из базы данных, но теперь давайте отключим интернет-соединение, чтобы активировать цикл.
Так что без подключения к интернету все кешируется в памяти. У меня есть доступ ко всем. Хорошо, теперь давайте активируем интернет-соединение и посмотрим, что произойдет.
Как видите, я загрузил только 6,60 КБ + 4,10 КБ = 10,70 КБ данных, но он волшебным образом загрузил мне 54,90 КБ данных для уведомлений, что невозможно, поскольку- У меня был доступ ко всем данным без подключения к интернету
- Я очистил их все, так что это было максимум 6,60 КБ, который был загружен. А также волшебным образом скачал 42.60 кБ из списка элементов (что составляет максимум 4,10 кБ)
4) Заключение
Так вот ... Когда я был в автономном режиме, я мог видеть все элементы, потому что он был кэширован в дисковую память, но когда я в сети, он загружает все, как положено, но для этого требуется 100ko просто "проверить, изменилось ли что-то"?
Но если я очищаю кеш и загружаю его снова, он загружает только реальный объем данных?
Там есть что-то, что определенно идет не так!
(Это все еще не объясняет 9 МБ)
Можете ли вы дать некоторые объяснения?
РЕДАКТИРОВАТЬ 3
5) Я сделал больше теста. Похоже, что каждый раз, когда вы заходите на сайт Firebase для проверки ваших данных, он загружает всю базу данных в ваш браузер ... и проверяет результат ...
Я обновляю страницу:
и проверьте загруженные данные:
Если вы проверите свою статистику данных, а затем вернетесь в представление данных, она будет загружена заново !!! Удивительно...
Так что, если вы часто проверяете свои данные, это будет стоить вам чертовски много денег.
6) Я провел другой тест, очистил дисковую память и затем снова подключился, и при каждом входе в систему токен устройства загружается в базу данных (для уведомлений). Ну ... это довольно удивительно, потому что он загружен и загружен (с 3 раза больше данных)! смотреть:
Но теперь, если я выйду из системы и войду снова (без очистки дисковой памяти), она не будет загружена снова при загрузке:
Итак ... Я не знаю, что сказать по этому поводу, но я надеюсь, что это поможет проверить ответ на вопрос