How to include Source Cache in cloud firestore realtime update in MVVM architecture android

早过忘川 提交于 2021-02-04 21:50:22

问题


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);
        }
    }
}

回答1:


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.



来源:https://stackoverflow.com/questions/53679460/how-to-include-source-cache-in-cloud-firestore-realtime-update-in-mvvm-architect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!