Я сталкиваюсь с очень странными результатами при работе базы данных Firebase в реальном времени для Android.Основная проблема:
- Когда я пытаюсь добавить дочерний элемент с двумя полями, метод onChildAdded возвращает вставленное значение для первого ключа и ноль для второго и не вызывается для второго значения вновь вставленногоchild.
- Когда я пытаюсь сделать то же самое с помощью valueEventListener, метод onDataChange вызывается дважды при создании нового дочернего элемента.В первом обратном вызове значение одного поля в возвращаемом и втором значении равно нулю, а во втором обратном вызове возвращаются оба обновленных значения.
У меня есть эта структура в моей базе данных firebase.
{
"users" : {
"-LOOlXqtc0XK3ZXLKFc6" : {
"Age" : 50,
"Name" : "Ali"
},
"-LOPIfgGQMhyMkRMcpTb" : {
"Age" : 80,
"Name" : "New Name"
}
}
}
И это мой код MainActivity:
mDatabase = FirebaseDatabase.getInstance();
mRef = mDatabase.getReference("users");
Этот код выполняется на данных вставкиНажатие кнопки.
private void runCode(View view){
String name = mInputText.getText().toString();
int age= Integer.parseInt(mInputNum.getText().toString());
String key = mRef.push().getKey();
mRef.child(key).child("Name").setValue(name);
mRef.child(key).child("Age").setValue(age);
}
И это метод чтения данных по нажатию кнопки с использованием valueEventListener.
private void readData(View view) {
//read data here
//this read data method has value listener not child listener
mRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Person data= dataSnapshot.getValue(Person.class);
Map<String,Object> data1= (Map<String, Object>) dataSnapshot.getValue();
Log.d(TAG, "onChildAdded: Name: "+data1.get("Name"));
Log.d(TAG, "onChildAdded: Age: "+data1.get("Age"));
Log.d(TAG, "This is Person: "+data);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
Вывод logcat такой: Это когда я нажимаю на метод Чтение данных дляв первый раз.
D/MyTag: onChildAdded: Name: Ali
D/MyTag: onChildAdded: Age: 50
D/MyTag: This is Person: Person{Name='Ali', Age=50}
И это вывод logcat, когда я вставляю нового потомка с именем = "Новое имя" и возрастом = 80.
D/MyTag: onChildAdded: Name: Ali
D/MyTag: onChildAdded: Age: 50
D/MyTag: This is Person: Person{Name='Ali', Age=50}
D/MyTag: onChildAdded: Name: New Name
D/MyTag: onChildAdded: Age: null
D/MyTag: This is Person: Person{Name='New Name', Age=0}
D/MyTag: onChildAdded: Name: Ali
D/MyTag: onChildAdded: Age: 50
D/MyTag: This is Person: Person{Name='Ali', Age=50}
D/MyTag: onChildAdded: Name: New Name
D/MyTag: onChildAdded: Age: 80
D/MyTag: This is Person: Person{Name='New Name', Age=80}
Метод обратного вызова выполняется отдельнодля каждого поля он возвращает по одному полю за раз, но это имеет смысл, что setField вызывается дважды, поэтому может быть, поэтому оно вызывается.Но с дочерним слушателем дело обстоит еще хуже.
Вот метод Read Code с реализацией childListener.
private void readData(View view) {
//read data here
mRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
Map<String,Object> data= (Map<String, Object>) dataSnapshot.getValue();
Person p=dataSnapshot.getValue(Person.class);
Log.d(TAG, "onChildAdded: Name: "+data.get("Name"));
Log.d(TAG, "onChildAdded: Age: "+data.get("Age"));
Log.d(TAG, "onChildAdded: Person is: "+p);
}
@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) {
}
});
}
Вот вывод logcat, когда я впервые нажимаю кнопку чтения данных:
D/MyTag: onChildAdded: Name: Ali
D/MyTag: onChildAdded: Age: 50
D/MyTag: onChildAdded: Person is: Person{Name='Ali', Age=50}
D/MyTag: onChildAdded: Name: New Name
D/MyTag: onChildAdded: Age: 80
D/MyTag: onChildAdded: Person is: Person{Name='New Name', Age=80}
И это вывод с добавлением нового ребенка с Name = "Usman" и age = 50
D/MyTag: onChildAdded: Name: Usman
D/MyTag: onChildAdded: Age: null
D/MyTag: onChildAdded: Person is: Person{Name='Usman', Age=0}
Только это происходит в обратном вызове.Возраст не возвращается, но значение правильно хранится в базе данных.
Пожалуйста, помогите.У меня подключен только один слушатель, и я всегда запускаю приложение после остановки запущенного процесса.Спасибо.