I have a lot of questions about handeling asynchronous database in my Android app.
Since I know that database is asynchronous, I've tried several things to handle it. As you can see in my code, I've two functions who need to use an array in my database. My first function (setArrayfromDatabase
) will apply changes on my array in my database and my second function (setAnotherArray
)need to use this array with changes applied from my first function. Here's my code :
FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myReff =database.getReference("server").child("user");
myReff.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Take the array from my database
final ArrayList<Integer> array_from_database;
GenericTypeIndicator<ArrayList<Integer>> genericTypeIndicator = new GenericTypeIndicator<ArrayList<Integer>>() {};
array_from_database = dataSnapshot.getValue(genericTypeIndicator) ;
System.out.println("1");
//use this array in this first function, and this function will modify it.
setArray_for_database(array_from_database);
myReff.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//this will be executed only if my array is changed (So only if my other function have been correctly executed
setAnotherArray(array_from_database);
System.out.println("3");
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Here's the code for setArray_for_database :
public void setArray_for_database(ArrayList<Integer> array_from_database){
FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myReff =database.getReference();
//Take the array from my database (gived in parameter)
final ArrayList<Integer> array = array_from_database;
myReff.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//this will be executed, even if data hasn't been changed because of the method (addListenerForSingleValueEvent)
System.out.println("2");
array.set(0,3);
Map<String, Object> chemainChild = new HashMap<>();
chemainChild.put("server/user/",array);
myReff.updateChildren(chemainChild);
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
}
Here's my trick. The purpose of having an myReff.addValueEventListener(new ValueEventListener()
inside another myReff.addListenerForSingleValueEvent(new ValueEventListener()
is to only execute onDataChange if my array from database has been changed. But the problem is that it's not the case.
Here's what's print first : 1, 3, 2 instead of 1, 2, 3 like I'm expecting with my trick.
Can you help me ? Am I handling the problem in the wrong way ? How must I do to only execute my second function, in condition that my array has been changed ? How can I keep my code waiting for changes in my database before executing something else ?
Hope you have understood me and feel free to ask me question if you doesn't understand something in my problem.