【问题标题】:Retrieving Data from FireStore using MVVM Architecture使用 MVVM 架构从 FireStore 检索数据
【发布时间】:2019-06-25 06:44:43
【问题描述】:

我正在尝试遵循 Android 架构原则,并希望您在我的 FireStore 数据库之上实现它们。

目前我有一个存储库Class,可以处理我对基础数据的所有查询。我有一个Fragment,它需要来自文档字段的Set<String> 键,我想知道检索这些数据的最佳方法是什么。在我之前的questionAlex Mamo 中建议使用InterfaceonCompleteListener,因为从Firestore 检索数据是Asynchronous

这种方法似乎有效,但我不确定如何将数据从这个Interface 提取到我的Fragment 的本地变量中。如果我想使用这些数据,我的代码是否必须在我对 abstract 方法的定义范围内?

如果要将数据从 Firestore 获取到我的 Fragment 我必须将片段中定义的 Interface 对象作为参数传递给我的存储库,我是否仍然遵循 MVVM 原则?

这是使用存储库查询 Firestore 数据库的推荐方法吗?

下面是我的Interface 和调用ViewModel 来检索数据的方法:

public interface FirestoreCallBack{
    void onCallBack(Set<String> keySet);
}

public void testMethod(){
    Log.i(TAG,"Inside testMethod.");
    mData.getGroups(new FirestoreCallBack() {
    //Do I have to define what I want to use the data for here (e.g. display the contents of the set in a textview)?
        @Override
        public void onCallBack(Set<String> keySet) {
            Log.i(TAG,"Inside testMethod of our Fragment and retrieved: " + keySet);
            myKeySet = keySet;
            Toast.makeText(getContext(),"Retrieved from interface: "+ myKeySet,Toast.LENGTH_SHORT).show();
        }
    });
}

我的ViewModel 调用存储库的方法:

private FirebaseRepository mRepository;
public void getGroups(TestGroupGetFragment.FirestoreCallBack firestoreCallBack){
    Log.i(TAG,"Inside getGroups method of FirebaseUserViewModel");
    mRepository.getGroups(firestoreCallBack);
}

最后我的 Repository 方法到 query 我的 FireStore 数据库:

public void getGroups(final TestGroupGetFragment.FirestoreCallBack firestoreCallBack){
    Log.i(TAG,"Attempting to retrieve a user's groups.");
    userCollection.document(currentUser.getUid()).get().addOnCompleteListener(
            new OnCompleteListener<DocumentSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                    if (task.isSuccessful()){
                        DocumentSnapshot document = task.getResult();
                        Log.i(TAG,"Success inside the onComplete method of our document .get() and retrieved: "+ document.getData().keySet());
                        firestoreCallBack.onCallBack(document.getData().keySet());
                    } else {
                        Log.d(TAG,"The .get() failed for document: " + currentUser.getUid(), task.getException());
                    }
                }
            });
    Log.i(TAG, "Added onCompleteListener to our document.");
}

已编辑

public void testMethod(){
    Log.i(TAG,"Inside testMethod.");
    mData.getGroups(new FirestoreCallBack() {
        @Override
        public void onCallBack(Set<String> keySet) {
            Log.i(TAG,"Inside testMethod of our Fragment and retrieved: " + keySet);
            myKeySet = keySet;
            someOtherMethod(myKeySet); //I know I can simply pass keySet.
            Toast.makeText(getContext(),"GOT THESE FOR YOU: "+ myKeySet,Toast.LENGTH_SHORT).show();
        }
    });

    Log.i(TAG,"In testMethod, retrieving the keySet returned: "+ myKeySet);
}

【问题讨论】:

  • 使myKeySet 变量全局化,并不意味着它可以简单地在onCallBack 方法之外使用,它仍然在回调中。
  • 所以为了将myKeySet 传递给另一个方法,我必须在onCallBack 方法中调用该方法吗?请查看我原始问题的编辑部分。
  • 是的,没错,你必须在onCallBack方法中调用它。
  • 感谢亚历克斯的帮助。您是否碰巧知道这种Interface 方法是否是使用存储库从底层 FireStore 数据库中抽象的最佳方法?
  • 如果这是最好的方法,我不知道该说什么,但如果它解决了您的问题,那么值得使用它。

标签: java android firebase mvvm google-cloud-firestore


【解决方案1】:

而不是interface,例如,我只使用LiveData 将数据带到recyclerview。

首先,我们必须创建我们的Firestore query。在此示例中,我列出了集合中的所有文档。

public class FirestoreLiveData<T> extends LiveData<T> {

    public static final String TAG = "debinf firestore";

    private ListenerRegistration registration;

    private CollectionReference colRef;
    private Class clazz;

    public FirestoreLiveData(CollectionReference colRef, Class clazz) {
        this.colRef = colRef;
        this.clazz = clazz;
    }


    EventListener<QuerySnapshot> eventListener = new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots, @Nullable FirebaseFirestoreException e) {
            if (e != null) {
                Log.i(TAG, "Listen failed.", e);
                return;
            }


            if (queryDocumentSnapshots != null && !queryDocumentSnapshots.isEmpty()) {
                List<T> itemList = new ArrayList<>();
                for (DocumentSnapshot snapshot : queryDocumentSnapshots.getDocuments()) {
                    T item = (T) snapshot.toObject(clazz);
                    itemList.add(item);
                    Log.i(TAG, "snapshot is "+snapshot.getId());
                }
                setValue((T) itemList);
            }
        }
    };

    @Override
    protected void onActive() {
        super.onActive();
        registration = colRef.addSnapshotListener(eventListener);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        if (!hasActiveObservers()) {
            registration.remove();
            registration = null;
        }
    }
}

接下来,我们在Repository中创建一个链接

public class Repository {

    public Repository() {
    }

    public LiveData<List<ProductsObject>> productListening(GroupObject group) {
        return new FirestoreLiveData<>(DatabaseRouter.getCollectionRef(group.getGroupCreator()).document(group.getGroupKey()).collection("ProductList"), ProductsObject.class);
    }

}

之后,我们创建我们的ViewModel

public class MyViewModel extends ViewModel {

    Repository repository = new Repository();

    public LiveData<List<ProductsObject>> getProductList(GroupObject groupObject) {
        return repository.productListening(groupObject);
    }

}

最后,在我们的MainActivityFragment 中,我们观察ou Firestore 中包含的数据:

    viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
    viewModel.getProductList(groupObject).observe(this, new Observer<List<ProductsObject>>() {
        @Override
        public void onChanged(@Nullable List<ProductsObject> productsObjects) {
            //Log.i(TAG, "viewModel: productsObjects is "+productsObjects.get(0).getCode());
            adapter.submitList(productsObjects);
        }
    });

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2018-02-07
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 2021-04-17
    • 1970-01-01
    • 2020-06-22
    • 2019-05-03
    • 2019-09-24
    相关资源
    最近更新 更多