Во время выполнения метода вам необходимо получить 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();
}
});