On an Android application which must works offline most of the time I need, when it's online, to do some synchronous operations for i.e. :
User myUser = MyclientFacade.getUser();
If (myUser.getScore > 10) {
DoSomething()
}
Where User is a POJO filled by Firebase;
The problem occurs when the Firebase cache is activated
Firebase.getDefaultConfig().setPersistenceEnabled(true);
and the user is already in cache and the data are updated on Firebase DB by a third party (or even by another device). Indeed when I query Firebase to get the User I obtain first the data from the cache and later a second change event with the latest data from the Firebase server, but it's too late!
Let's see the synchronous method MyclientFacade.getUser() :
Public User getUser() {
Firebase ref = myFireBaseroot.child("User").child(uid);
ref.keepSynced(true);
/* try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
final CountDownLatch signal = new CountDownLatch(1);
ref.addListenerForSingleValueEvent(new ValueEventListener() {
//ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
this.user = dataSnapshot.getValue(User.class);
signal.countDown();
}
@Override
public void onCancelled(FirebaseError firebaseError) {
signal.countDown();
}
});
signal.await(5, TimeUnit.SECONDS);
ref.keepSynced(false);
return this.user;
}
I obtain the same behavior if I use addValueEventListener
or addListenerForSingleValueEvent
mixed with ref.keepSynced
:
Let's say my user's score value in cache is 5 and from Firebase DB is 11.
When I call getUser
I will obtain the score of 5 (Firebase ask cache first) so I will not call the doSomething()
method.
If I uncomment the Thread.sleep()
code from my example, the Firebase cache will have enough time to be updated and my getUser
will return the correct score value (11).
So how can I directly ask the latest value directly from server side and bypass the cache?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…