提问者:小点点

如何在 MVVM 架构Android中的云火堆实时更新中包含源缓存


在我的应用程序中,我使用的是android MVVM架构,因此为了从云Firestore检索数据,我正在使用图层,因此我创建了另一个类(FirebaseQueryLiveData)以从Firestore获取结果。因此,使用我的代码,我获得了实时更新,但无法添加Firestore的缓存源功能。我想通过添加缓存来启用离线模式。如何添加它。

产品视图型号.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个答案

匿名用户

对于 Android 和 iOS,Cloud Firestore 默认启用离线持久性。这意味着您的应用将在断开连接的短到中段时间内工作。

是的,您可以在DocumentReference.get(Source Source)和Query.get(Source source)方法的帮助下指定源。

默认情况下,get() 会尝试通过等待来自服务器的数据来尽可能提供最新数据,但如果脱机且无法访问服务器,它可能会返回缓存数据或失败。可以通过源参数更改此行为。

因此,我们现在可以将参数传递给 DocumentReference查询源,以便我们可以像这样强制从 chache 检索数据:

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

在这种情况下,我们强制仅从缓存中检索数据,但是当您说要获取实时更新时,为什么要使用此功能?因此,对于您的用例,我不明白为什么要从缓存中获取数据。