Firebase android最佳地读取数据

时间:2018-06-03 13:45:42

标签: java android firebase firebase-realtime-database

在执行该方法期间,您需要从同一分支获取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 :(得分:0)

嵌套侦听器没有任何问题,只要您根据life-cycle of your activity删除它们即可。所以你的代码看起来正确。有一种方法可以使用自定义回调实现相同的功能,但不需要使用它们而不是嵌套侦听器的直接示例。

答案 1 :(得分:0)

我决定将我的逻辑从侦听器转移到服务器部分,因为没有用户参与,并且不需要客户端 我在JavaScript中使用了Firebase功能......