Firebase Android оптимально читает данные - PullRequest
0 голосов
/ 03 июня 2018

Во время выполнения метода вам необходимо получить 2 набора данных из одной и той же ветви.Затем скорректируйте значения и напишите обратно.Как правильно организовать этот метод?Я сделал это, вложив слушателей.Есть ли более правильный подход?И как мне заставить этот метод возвращать результат (например, логический), когда команда записи Firebase успешно выполняется?

Код метода:

public static void UpdateBalancesInFB (final long DateMove, final double DeltaValue, DatabaseReference FBRef){
    //TODO: как получить успешное выполнение метода?!
    final DatabaseReference mDBref = FBRef.child(MyTypesAndUtils.sFB_Balances);
    final boolean result = false;

    /*получаем с Firebase выгрузку последней записи и данных следующих за Date_min */
    final Query mQuery = mDBref.orderByKey();
    mQuery.limitToLast(1).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            final long[] Date_last = {DateMove};
            final double[] Value_last = {DeltaValue};

            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                Date_last[0] = Long.valueOf(snapshot.getKey());
                Value_last[0] = snapshot.getValue(Double.class);
            }
            mQuery.startAt(String.valueOf(DateMove)).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    boolean mark = false;
                    Map<String, Object> mQueryBalances = new HashMap<>();
                    for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                        mQueryBalances.put(snapshot.getKey(), snapshot.getValue());
                        mark = true;
                    }
                    /*корректируем значения остатков после даты движения*/
                    for (HashMap.Entry<String, Object> entry : mQueryBalances.entrySet()) {
                        Date_last[0] = Long.valueOf(entry.getKey());
                        Value_last[0] = Double.valueOf(entry.getValue().toString()) + DeltaValue;
                        mQueryBalances.put(entry.getKey(), Value_last[0]);
                    }

                    /*дополняем коллекцию недостающими элементами до даты движения и 1 элемент после нее*/
                    //это возможно только если mQueryBalances пустой
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTimeInMillis(Date_last[0]);         //последняя запись остатков
                    calendar.set(Calendar.DAY_OF_MONTH, 1);         //переводим на 1й день месяца (на всякий случай)

                    while (!mark) {                                 // это возможно только если mQueryBalances пустой
                        calendar.add(Calendar.MONTH, 1);
                        Date_last[0] = calendar.getTimeInMillis();
                        if (Date_last[0] <= DateMove)
                            mQueryBalances.put(String.valueOf(Date_last[0]), Value_last[0]);
                        else{
                            mQueryBalances.put(String.valueOf(Date_last[0]), Value_last[0]+DeltaValue);
                            mark = true;
                        }
                    }

                    /*Записываем в Firebase*/
                    mDBref.updateChildren(mQueryBalances, new DatabaseReference.CompletionListener() {
                        @Override
                        public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                            //result = true;
                        }
                    });
                }

Код вызова этого метода также выполняетсявнутри слушателя:

myRef.child(MyTypesAndUtils.sFB_Movements).child(mMove_output.getKeyFB()).setValue(mMove_output).addOnSuccessListener(this, new OnSuccessListener<Void>() {
        @Override
        public void onSuccess(Void aVoid) {
            long Date2, Date1;
            double Value2, Value1;

            Date2 = mMove_output.getDateInMilisec();
            Value2 = mMove_output.getValue()*mMove_output.getKind();
            if (mMove_input != null) {
                Date1 = mMove_input.getDateInMilisec();
                Value1 = mMove_input.getValue()*mMove_input.getKind();
                if (Date2==Date1)
                    MyTypesAndUtils.UpdateBalancesInFB(Date2, (Value2-Value1), myRef);
                else {
                    MyTypesAndUtils.UpdateBalancesInFB(Date1, (-Value1), myRef);
                    MyTypesAndUtils.UpdateBalancesInFB(Date2, Value2, myRef);
                }
            }
            else    MyTypesAndUtils.UpdateBalancesInFB(Date2, (Value2), myRef);

            Toast.makeText(getApplicationContext(), "Сохранение произошло", Toast.LENGTH_SHORT).show(); //TODO: переписать в string
            finish();
        }
    });

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

Я решил перенести свою логику со слушателей на серверную часть, так как в ней нет участия пользователя, а клиент не нужен. Я использовал функцию Firebase в JavaScript ...

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

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

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