How To Include Source Cache In Cloud Firestore Realtime Update In MVVM Architecture Android
In my app i am using android MVVM architecture, so for retrieving data from cloud firestore i am using layers so i create one more class (FirebaseQueryLiveData) for getting result from firestore. So with my code i am getting the realtime update but not able to add the Cache Source feature of firestore.I want to enable offline mode by adding cache soure. How to add it.
ProductViewModel.java
public class ProductViewModel extends AndroidViewModel {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private MediatorLiveData<List<ProductModel>> productListLiveData;
private FirebaseQueryLiveData liveData;
public ProductViewModel(@NonNull Application application) {
super(application);
}
public LiveData<List<ProductModel>> getProductList() {
productListLiveData = new MediatorLiveData<>();
completeProductList();
return productListLiveData;
}
private void completeProductList() {
Query query = db.collection("mainCollection").document("productList")
.collection("productCollection");
liveData = new FirebaseQueryLiveData(query);
productListLiveData.addSource(liveData, new Observer<QuerySnapshot>() {
@Override
public void onChanged(QuerySnapshot queryDocumentSnapshots) {
if (queryDocumentSnapshots!= null){
List<ProductModel> productModelList = new ArrayList<>();
for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots){
ProductModel model = documentSnapshot.toObject(ProductModel.class);
productModelList.add(model);
}productListLiveData.setValue(productModelList);
}
}
});
}
FirebaseQueryLiveData.java
public class FirebaseQueryLiveData extends LiveData<QuerySnapshot> {
private MyValueEventListener listener = new MyValueEventListener();
private Query query;
Source source = Source.CACHE;
private boolean listenerRemovePending = false;
private ListenerRegistration registration;
private Handler handler = new Handler();
private final Runnable removeListener = new Runnable() {
@Override
public void run() {
registration.remove();
listenerRemovePending = false;
}
};
public FirebaseQueryLiveData(Query query) {
this.query = query;
}
@Override
protected void onActive() {
super.onActive();
if (listenerRemovePending){
handler.removeCallbacks(removeListener);
}else {
registration= query.addSnapshotListener(listener);
}
listenerRemovePending= false;
}
@Override
protected void onInactive() {
super.onInactive();
handler.postDelayed(removeListener, 2000);
listenerRemovePending=true;
}
private class MyValueEventListener implements EventListener<QuerySnapshot> {
@Override
public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
setValue(queryDocumentSnapshots);
}
}
}
Answer
For Android and iOS, Cloud Firestore has offline persistence enabled by default. This means that your app will work for short to intermediate periods of being disconnected.
And yes, you can specify the source with the help of the DocumentReference.get(Source source) and Query.get(Source source) methods.
By default,
get()
attempts to provide up-to-date data when possible by waiting for data from the server, but it may return cached data or fail if you are offline and the server cannot be reached. This behavior can be altered via the Source parameter.
So we can now pass as an argument to the DocumentReference
or to the Query
the source so we can force the retrieval of data from the chache only
like this:
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference docIdRef = db.collection("tests").document("fOpCiqmUjAzjnZimjd5c");
docIdRef.get(Source.CACHE).addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
//Get data from the documentSnapshot object
}
});
In this case, we force the data to be retrieved from the cache only but why to use this feature when you say that you want to get realtime updates? So for your use-case I don't see why you would get the data from cache.
Related Questions
- → should I choose reactjs+f7 or f7+vue.js?
- → Phonegap Android write to sd card
- → Local reference jquery script in nanohttpd (Android)
- → Click to navigate on mobile devices
- → How to allow api access to android or ios app only(laravel)?
- → Access the Camera and CameraRoll on Android using React Native?
- → React native change listening port
- → What is the default unit of style in React Native?
- → Google play market autocomplete icon
- → Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `ListView`
- → Using Laravel with Genymotion
- → react native using like web-based ajax function
- → react native pdf View