异步Firebase数据库未更新类成员变量

时间:2018-07-16 18:41:05

标签: java android firebase firebase-realtime-database

MyApplication的用途:1)读取firebase db的活动类,2)根据从firebase db读取的数据更新类成员变量,3)根据从firebase db内的值更新的类成员变量评估凭据

public MyApplication extends AppCompatActivity implements FireBaseDataListener{
private static int N; /* number of firebase keys *//* static to be accessed in db read */
private Button Nbtn;
private FirebaseDataBase mFirebaseDataBase;
private FirebaseReference mFirebaseReference;
... instantiated class member variables in @OnCreate...
... create setters and getters and add listeners ...

public void processing(){
 /* here is the issue, normally i would think this.N updates
    before checkCredentials is called. wrong! since the asynchronous
    design of firebase db i'm perplexed what to do in order to get
    this.N to update before checkCredentials() is called.
    due to this in checkCredentials i get N==0 not N>0.
    however, i peek at the log.d printout and see the value updates
    so i trace the program and see checkCredentials evaluates 
    way before readNfromFireBase is done. */
 Log.d.("...", "before firebase read");
 readNfromFireBase(this);
 Log.d.("...", "before checkCredentials");
 checkCredentials();
}

public void checkCredentials(){
 Log.d.("...", "inside checkCredentials");
 if(this.N == 0) { empty firebase launches dialog warning no keys }
 elseif(this.N > 0) { Log.d("log#1", "N: " + N); }
 else { Log.d("log#0", "N: " + N + " this should never happen but just in case.") }
}

public void readNfromFireBase(FireBaseDataListener listener){
listener.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    ... for each loop to iterate over the data
    /* before sending data to callback i print and verify the number
       of keys is correct, so i know i have the correct data */
    Log.d.("...", "before listener");
    this.N = listener.onKeyCallback(data); // WARNING#0 this.N (i'm aware)
    Log.d.("...", "after listener");
  }
  @Override
  public void onCancelled(DatabaseError databaseError) {
    System.out.println("The read failed: " + databaseError.getCode());
  }
}

/* Override for FireBaseDataListener */

@Override public onKeyCallBack(int nKeys){
 Log.d.("...", "inside callback listener");
 this.N = nKeys; // WARNING#1 this.N (i'm aware)
 return this.N;
}

} //end of my application class

interface FireBaseDataListener{
void onKeyCallback(int nKeys);
} // end of interface

关于WARNING#0和WARNING#1的注释-出于学习目的,有人可以阐明一些更合适的方法来更新侦听器例程中或重写重写内的值,换句话说,我应该在哪里更新警告#0或警告#1?

示例执行-很奇怪,但是却是这样

"before firebase read"
"before listener"
"before checkCredentials"
"inside checkCredentials"
"inside callback listener"
"after listener"

示例执行-应该应该如此,但事实并非如此。

"before firebase read"
"before listener"
"inside callback listener"
"after listener"
"before checkCredentials"
"inside checkCredentials"

简而言之,代码正在评估数据库读取返回之前的未来功能。

1 个答案:

答案 0 :(得分:0)

回调将在访问Firebase数据时更好地工作。

/* callback interface */
public interface FireBaseCallBack {
 void doCallBack(SomeClass sc);
}

public class FireBaseHandler{
 private FirebaseDatabase mFirebaseDatabase;
 private DatabaseReference mFireBaseReference;

 public FireBaseHandler(){
  this.mFirebaseDatabase = FirebaseDatabase.getInstance();
  this.mFireBaseReference = mFirebaseDatabase.getReference();

 public void operationOnFireBase(final FireBaseCallBack callback){
  mFireBaseReference.addListenerForSingleValueEvent(new ValueEventListener(){
   @Override void onDataChange(@NonNull DataSnapshot dataSnapshot){
    SomeClass temp = new SomeClass();
    temp.set/get on data in firebase
    callback.doCallBack(temp);
   }
  }
 }
}

public class SomeClass{
 private FireBaseHandler mFireBaseHandler;
 void someFunction(){
  mFireBaseHandler.operationOnFireBase(new FireBaseCallBack()){
    @Override void doCallBack(SomeClas sc){
     ...
    }
   });
  }
 }
}