【问题标题】:FirestoreAdapter not working to populate a Recycler ViewFirestoreAdapter 无法填充回收站视图
【发布时间】:2018-06-01 22:54:36
【问题描述】:

我是 Android 新手,我决定使用 Cloud Firestore 作为我的数据库,并使用 RecyclerView 在我的 MainActivity 中填充列表。我认为在 Firestore 中使用 Firebase-UI 会非常简单,但我无法弄清楚为什么我的 RecyclerView 中没有填充任何内容。作为参考,here is the Firebase UI pagehere is the example code 是我的应用程序的基础。我要做的就是填充用户保存在数据库中的“课程”列表(Course.java 未显示在下面,因为它只是一个带有名称、日期等的简单 POJO)。

主活动:

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.Query;
import com.lorin.deadlineschmedline.R;
import com.lorin.deadlineschmedline.adapters.CourseAdapter;

import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity
        implements CourseAdapter.OnCourseSelectedListener,
        PopupMenu.OnMenuItemClickListener {

private FirebaseFirestore mFirestore;
private Query mQuery;
private FirebaseUser mCurrentUser;

private RecyclerView.Adapter mAdapter;

private static final String TAG = "MainActivity";
private static final int RC_SIGN_IN = 9001;
private static final int LIMIT = 50;

@BindView(R.id.rv_course_item_list)
RecyclerView mCourseRecyvlerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            showPopup(view);
        }
    });

    // Enable Firestore logging
    FirebaseFirestore.setLoggingEnabled(true);

    // Firestore
    mFirestore = FirebaseFirestore.getInstance();
    mQuery = mFirestore.collection("courses").whereEqualTo("name", true).limit(LIMIT);
    mAdapter = new CourseAdapter(mQuery, this) {
        @Override
        protected void onDataChanged() {
            // Show/hide content if the query returns empty.
            if (getItemCount() == 0) {
                mCourseRecyvlerView.setVisibility(View.VISIBLE);
                //mEmptyView.setVisibility(View.VISIBLE);
            } else {
                mCourseRecyvlerView.setVisibility(View.VISIBLE);
                //mEmptyView.setVisibility(View.GONE);
            }
        }

        @Override
        protected void onError(FirebaseFirestoreException e) {
            // Show a snackbar on errors
            Snackbar.make(findViewById(android.R.id.content),
                    "Error: check logs for info.", Snackbar.LENGTH_LONG).show();
        }
    };

    mCourseRecyvlerView.setLayoutManager(new LinearLayoutManager(this));
    mCourseRecyvlerView.setAdapter(mAdapter);
}

private void showPopup(View v) {
    PopupMenu popup = new PopupMenu(this, v);
    MenuInflater inflater = popup.getMenuInflater();
    inflater.inflate(R.menu.add_component_menu, popup.getMenu());
    popup.setOnMenuItemClickListener(this);
    popup.show();
}

@Override
public void onStart() {
    super.onStart();
    mAdapter.startListening();
}

@Override
public void onStop() {
    super.onStop();

    if (mAdapter != null) {
        mAdapter.stopListening();
    }
}

@Override
public boolean onMenuItemClick(MenuItem item) {
    switch(item.getItemId()) {
        case R.id.add_course:
            startActivity(new Intent(MainActivity.this, AddCourseActivity.class));
            return true;
        case R.id.add_course_component:
            startActivity(new Intent(MainActivity.this, AddCourseComponentActivity.class));
            return true;
        default:
            return true;
    }
}

@Override
public void onCourseSelected(DocumentSnapshot restaurant) {
    // Go to the details page for the selected activity
    Intent intent = new Intent(this, AddCourseActivity.class);
    startActivity(intent);

    //overridePendingTransition(R.anim.slide_in_from_right, R.anim.slide_out_to_left);
}

}

我尝试使用调试器单步执行 MainActivity,但是当我查询数据库时,我无法确定从 Firestore 返回的内容(这可能是问题所在)。任何想法和反馈将不胜感激!

【问题讨论】:

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


    【解决方案1】:

    为了使其工作,您需要开始监听更改,为此,请在您的 MainActivity 类中的 onStart() 方法中调用适配器对象上的 startListening() 方法,如下所示:

    @Override
    public void onStart() {
        super.onStart();
        mAdapter.startListening();
    }
    

    要停止收听,请使用以下代码:

    @Override
    public void onStop() {
        super.onStop();
    
        if (mAdapter != null) {
            mAdapter.stopListening();
        }
    }
    

    【讨论】:

    • 我尝试更新这两种方法(并反映了上面的更改),但不幸的是这并没有解决问题。我仍然无法在回收站视图中显示任何内容。
    【解决方案2】:

    原来是 Firestore 查询的问题。以前,我用过:

    mQuery = mFirestore.collection("courses").whereEqualTo("name", true).limit(LIMIT);

    但是,在进行 Firestore 查询时,您似乎必须使用 orderBy() 方法。使用以下方法可以解决问题:

    mQuery = mFirestore.collection("courses").orderBy("name").limit(LIMIT);

    现在我的数据按预期显示在 RecyclerView 中。

    【讨论】:

    • whereEqualToorderBy 是两种不同类型的过滤数据。第一个是在数据库中搜索所有值为 true 的名称,第二个是按名称对结果进行排序。因此,第二个查询只是获取结果的另一种方式,但没有开始监听更改,您的所有查询都不会反映在您的 RecyclerView 中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-18
    • 2020-01-22
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    相关资源
    最近更新 更多