Android:如何使用Firebase正确获取数据?

Android:如何使用Firebase正确获取数据?,android,firebase,asynchronous,google-cloud-firestore,Android,Firebase,Asynchronous,Google Cloud Firestore,我正在用Firebase开发我的第一个Android应用程序,我喜欢它。我的问题是,我应该如何正确地从Firebase数据库获取数据?我对一次获取数据,然后再使用该数据获取更多数据感到有点困惑 我基本上是把“OnCompleteListeners”一个套在另一个里面,这种模式让我感到不安。有更好更合适的方法吗 以下是我目前的做法: //This is a weather app, users can monitor different weather stations //We first

我正在用Firebase开发我的第一个Android应用程序,我喜欢它。我的问题是,我应该如何正确地从Firebase数据库获取数据?我对一次获取数据,然后再使用该数据获取更多数据感到有点困惑

我基本上是把“OnCompleteListeners”一个套在另一个里面,这种模式让我感到不安。有更好更合适的方法吗

以下是我目前的做法:

//This is a weather app, users can monitor different weather stations 

//We first get the weather stations that the current user owns:
// I used two collections in this approach, "ownership" permission is read only to the user
DocumentReference docRef = mDatabase.collection("ownership").document( mUser.getUid() );

docRef.get().addOnCompleteListener( new OnCompleteListener<DocumentSnapshot>() {

    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {

        if ( task.isSuccessful() ) {

            DocumentSnapshot document = task.getResult();
            if ( document.exists() ) {

                Map<String, Object> data = document.getData();
                if ( data != null && data.containsKey("stations") ) {

                    // data is an string array, here is my ugly solution:
                    stationIds = data.get("stations").toString().replaceAll("[\\[\\]]", "").split(",");

                    if ( stationIds.length != 0 ) {

                        for ( int i = 0; i < stationIds.length; i++ ) {

                            // Now that I have the stations IDs I can get its data:
                            // !! the collection "stations" have read and write permission
                            // THIS PATTERN SEEMS VERY REDUNDANT!
                            DocumentReference docRef = mDatabase.collection("stations").document(stationIds[i]);
                            docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                                @Override
                                public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                                    if (task.isSuccessful()) {
                                        DocumentSnapshot document = task.getResult();
                                        if (document.exists()) {
                                            Map<String, Object> data = document.getData();
                                            Log.d(TAG, "Document Snapshot: " + document.getData());

                                            if ( data != null && data.containsKey("name") ) {
                                                LinearLayout ll_root = MainActivity.this.findViewById(R.id.ll_station_list);

                                                LinearLayout ll_new = new LinearLayout(MainActivity.this);
                                                ll_new.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                                                ll_new.setPadding(20,50,20,20);

                                                TextView tv_station_title = new TextView(MainActivity.this);
                                                tv_station_title.setText(data.get("name").toString());
                                                ll_new.addView( tv_station_title);
                                                ll_root.addView( ll_new );


                                                ll_new.setOnClickListener( new View.OnClickListener() {
                                                    @Override
                                                    public void onClick(View v) {
                                                        Intent intent = new Intent(MainActivity.this, LiveStation.class);
                                                        startActivity(intent);
                                                    }
                                                });
                                            }

                                        } else {
                                            Log.w(TAG, "Station not found");
                                        }
                                    } else {
                                        Log.w(TAG, "Unable to get station");
                                    }
                                }
                            });
                        }
                    }
                }

                Log.d( TAG, "Document Snapshot: " + document.getData() );

            } else {
                Log.w(TAG, "No document found");
            }
        } else {
            Log.w(TAG, "Get user stations failed: " + task.getException() );
        }
    }
});
//这是一个天气应用程序,用户可以监控不同的气象站
//我们首先获取当前用户拥有的气象站:
//在这种方法中,我使用了两个集合,“所有权”权限对用户是只读的
DocumentReference docRef=mDatabase.collection(“所有权”).document(mUser.getUid());
docRef.get().addOnCompletListener(新的OnCompletListener()){
@凌驾
未完成的公共void(@NonNull任务){
if(task.issusccessful()){
DocumentSnapshot document=task.getResult();
if(document.exists()){
Map data=document.getData();
if(data!=null&&data.containsKey(“站点”)){
//数据是一个字符串数组,下面是我的解决方案:
stationIds=data.get(“stations”).toString().replaceAll(“[\\[\\]]”和“).split(“,”);
如果(StationId.length!=0){
for(int i=0;i

我不太熟悉Android中的异步调用。通常我会创建一个与数据库对话的模型,并且可以从应用程序结构中的任何位置调用它,但是使用Firebase似乎无法做到这一点。似乎每个视图都需要自己对数据库的唯一调用。或者可能我的想法全错了。

看一看,你可以在活动中的任何地方调用
readData()
方法。代码对我来说都很好。如果你不喜欢嵌套的水平,考虑一下你自己的简单界面,就像亚历克斯所展示的答案一样。还可以看看Firebase的同事Doug写的这篇很棒的博文:。与Firebase合作了几天,现在这个概念更有意义了。我曾试图用全局变量创建类,以使这些属性“可检索”,但这毫无意义,它打乱了异步的整个概念。我会继续做我正在做的事情。感谢您的帮助和反馈!