Ответ 1
(я буду размещать здесь, поскольку его легче управлять моими комментариями)...
Решение не найдено.
* ОБНОВЛЕНИЕ 4: найденное решение **
После многих попыток и большого количества комментариев решение было окончательно найдено, очевидно, что OP имел метод инкремента в другом классе и переместил его в тот же класс, который использовался для решения проблемы.
Насколько это возможно, на мой взгляд, возможно, это связано с проблемой concurrency в транзакции, возможно, проблема заключалась в том, что она создавала цикл самостоятельно. Ваша деятельность начинается, позже вы создаете экземпляр FirebaseController
, который в какой-то момент уволил метод increment
, выполнив асинхронное выполнение, которое заканчивается (каким-то образом заканчивается?), И оно снова запускает вашу активность.
См. ниже о неудачных попытках (но устранение неполадок).
Я пытался отлаживать. Он не активировался ни на одной из этих линий. Занимает меня к группе файлов Android (например, View.java). Когда я "Бегу в курсор" (пропустить следующую контрольную точку отладки), перезапускается.
Можете ли вы проверить, не является ли отображаемый клик в runnable нулевым?
Runnable runnable = new Runnable() {
@Override
public void run() {
// if not null do this
clicked.setEnabled(true);
// if null print some log
// ...
}
};
Вы используете Step Into или Step over при отладке (если вы углубляетесь в иерархию классов, которые вы можете использовать с помощью Step Into (F5), можете ли вы попробовать отладку с помощью Step Over (F6))?
Если мы найдем ответ, я отправлю его здесь:
ОБНОВЛЕНИЕ 1:
MutableData#setValue(java.lang.Object)
В документации объясняется, как это работает:
Установите данные в этом месте на заданное значение. Нативные типы принятые этим методом для значения, соответствуют типам JSON:
Boolean
Long
Double
Map<String, Object>
List<Object>
Кроме того, вы можете установить экземпляры своего собственного класса в это место, если они удовлетворяют следующим ограничениям:
Класс должен иметь конструктор по умолчанию, который не принимает аргументов. класс должен определять публичные геттеры для назначаемых свойств. Свойства без публичного getter будут установлены в их значение по умолчанию когда экземпляр десериализован
Попробуйте использовать другой тип данных, предложенный другими разработчиками:
измените параметр #setValue
на объект вышеприведенного списка и #getValue
также верните объект, попробуйте применить его к правильному тип, возможно, вы могли бы использовать Integer
class
ОБНОВЛЕНИЕ 2:
Является ли ваша схема данных примерно такой?
{
"campaings": {
"key": {
"count": "1",
"users": {
"-JRHTHaIs-jNPLXOQivY": {
"count": "1",
...
},
...
}
...
},
"other-key": {
...
}
...
}
}
Вот что я делаю из фрагментов кода, вы можете уточнить меня, если я допустил ошибку.
// here we are searching for the current reference in Campaings/key
DatabaseReference database = FirebaseDatabase.getInstance().getReference().child("Campaigns").child(key);
int preIncrementUserCount = Integer.parseInt(button.getText().toString());
final int incrementedUserCount = ++preIncrementUserCount;
button.setText(String.valueOf(incrementedUserCount));
database.runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
// here we are searching for the current count value in
// Campaings/key/count
Integer currentValue = mutableData.child("count").getValue(Integer.class);
if (currentValue == null) {
// do something...
} else {
// here we are setting the count value in Campaings/key/count
mutableData.child("count").setValue(++currentValue);
}
// here we are setting the count value in Campaings/key/users/UUID/count
mutableData.child("users").child(getUid()).child("count").setValue(incrementedUserCount);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {
if (databaseError != null) {
Log.e(TAG, "Error: " + databaseError.getMessage());
}
System.out.println("Transaction completed");
}
});
Точка примера кода должна иллюстрировать выполняемые вами схемы схемы данных (опять же, исправьте меня в любой части, если я допустил ошибку), но, пожалуйста, поместите databaseError
в журнал onComplete
для целей отладки
ОБНОВЛЕНИЕ 3
Из документации:
doTransaction() будет вызываться несколько раз и должен иметь возможность обрабатывать нулевые данные. Даже если на вашем удаленном компьютере имеются существующие данные базы данных, он не может быть локально кэширован, когда функция транзакции выполняется.
Попробуйте изменить эту часть:
if (currentValue == null) {
// do something...
} else {
// here we are setting the count value in Campaings/key/count
mutableData.child("count").setValue(++currentValue);
}
Что-то вроде:
if (mutableData.child("count").getValue() == null) {
// print something...
// Log.d(TAG,"Value at some point was null");
// or maybe (just to test)
// mutableData.child("count").setValue(1);
} else {
// here we are setting the count value in Campaings/key/count
mutableData.child("count").setValue(++currentValue);
}
P.S: Я оставляю решения, если какой-либо человек в предсказуемом будущем может устранить что-то похожее на это