How to bypass the Firebase cache to refresh data (in Android app)?
This was a problem that was causing me a lot of stress in my application too.
I tried everything, from changing .addListenerForSingleValueEvent()
to .addValueEventListener()
to trying to creatively use .keepSynced()
to using a delay (the Thread.sleep()
method you have described above) and nothing really worked consistently (even the Thread.sleep()
method, which wasn't really acceptable in a production app didn't give me consistent results).
So what I did was this: after creating a Query object and calling .keepSynced()
on it, I then proceed to write a mock/token object in the node I'm querying and THEN in that operation's completion listener, I do the data retrieval I want to do, after deleting the mock object.
Something like:
MockObject mock = new MockObject();
mock.setIdentifier("delete!");
final Query query = firebase.child("node1").child("node2");
query.keepSynced(true);
firebase.child("node1").child("node2").child("refreshMock")
.setValue(mock, new CompletionListener() {
@Override
public void onComplete(FirebaseError error, Firebase afb) {
query.addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot data) {
// get identifier and recognise that this data
// shouldn't be used
// it's also probably a good idea to remove the
// mock object
// using the removeValue() method in its
// speficic node so
// that the database won't be saddled with a new
// one in every
// read operation
}
public void onCancelled(FirebaseError error) {
}
});
}
});
}
This has worked consistently so far for me! (well, for a day or so, so take this with a grain of salt). It seems like doing a write operation before reading somehow bypasses the cache, which makes sense. So the data comes back fresh.
The only downside is the extra write operation before the read operation, which may cause a small delay (obviously use a small object) but if that's the price for always fresh data, I'll take it!
Hope this helps!
Is it possible for the app to open already with the latest data obtained by firebase?
You should explain a bit more, so we understand your use case. Anyways, i'll try to answer with what I have understood.
You can use sqflite
package to cache the data, i.e. it will be stored to the local storage. Get started: https://pub.dev/packages/sqflite
It will be fairly complex, even unnecessary if the size of your data is small.
If you have huge amount of data that doesn't change frequently, then go for it.
So how it will work is like this:
First you'll check whether the data has changed in Firestore or not.
Case 1: If it didn't then you'll display data from your local sqflite db.
Case 2: If it did change, then, you'll display data from Firestore, and at the same time update your local db with the new data.
Again, this is very superfluous if your data size is be small/it changes very frequently.
Related Topics
Using Audiotrack in Android to Play a Wav File
How to Keep a Button as Pressed After Clicking on It
How to Prevent The Activity from Loading Twice on Pressing The Button
Generating iOS and Android Icons in Cordova/Phonegap
Speechrecognizer Causes Anr... I Need Help with Android Speech API
Disable Webview Touch Events in Android
Android Sqlitedatabase Query with Like
Google Analytics Blocks Android App
Android Detect Webview Url Change
Backup/Restore Sqlite Db in Android
Listfragment Does Not Accept My Layout
How Disable/Remove Android Activity Label and Label Bar
Easier Way to Get View's Id (String) by Its Id (Int)
Imageview Adjustviewbounds Not Working
Android Studio Where Is Gradle.Properties File
Detecting Webview Error and Show Message