我在Android应用程序中有很多关于handeling异步数据库的问题。
因为我知道数据库是异步的,所以我尝试了几件事来处理它。正如您在我的代码中看到的那样,我需要在数据库中使用数组的两个函数。我的第一个函数(setArrayfromDatabase
)将在我的数据库中对我的数组应用更改,而我的第二个函数(setAnotherArray
)需要使用此数组,并在第一个函数中应用更改。这是我的代码:
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) {
}
});
这里是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) {}
});
}
这是我的伎俩。在另一个myReff.addValueEventListener(new ValueEventListener()
内部使用myReff.addListenerForSingleValueEvent(new ValueEventListener()
的目的是仅在我的数据库中的数组已更改时才执行onDataChange。但问题是事实并非如此。
这是第一次打印的内容:1,3,3而不是1,2,3,就像我期待的一样。
答案 0 :(得分:1)
改变这个:
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");
}
到此:
final FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myReff = database.getReference();
myReff.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
DatabaseReference ref2 = database.getReference();
//Take the array from my database (gived in parameter)
final ArrayList<Integer> array = array_from_database;
System.out.println("2");
array.set(0,3);
Map<String, Object> chemainChild = new HashMap<>();
chemainChild.put("server/user/",array);
myReff.updateChildren(chemainChild);
System.out.println("3");
}
上面可能缺少某些代码,但您可以添加方法public void setArray_for_database(ArrayList<Integer> array_from_database){
中的代码,以实现此目的。
由于onDataChange
是异步的,意味着程序将继续执行,即使仍未检索到数据,这是唯一的方法。
你得到1-3-2的原因是因为:
最好的办法是在onDataChange
以上将解决您在问题中遇到的异步问题。但你真的应该对数据进行非规范化。
阅读本文以了解更多信息:https://firebase.googleblog.com/2013/04/denormalizing-your-data-is-normal.html