【问题标题】:How do I read all the data of all keys except a specific one from Firebase Database?如何从 Firebase 数据库中读取除特定键之外的所有键的所有数据?
【发布时间】:2017-05-31 10:43:51
【问题描述】:

我希望我的应用从 Firebase 数据库中读取所有键中的数据。

这是我的数据库的快照 。

app_name 下的键代表一个用户,用户键中的所有键都包含一些数据。我需要能够从每个这样的用户密钥中读取数据除了用户本身(如读取除我添加的数据之外的所有数据)。我显然不知道所有用户的密钥,而且该列表可以在以后扩展或最小化。我可以使用FirebaseDatabase.getInstance.getReference.child(string) 访问的唯一级别是在应用程序名称下。有没有办法读取每个用户键内的键内的数据并以 List ViewRecycler Adapter 的形式显示内容?

编辑:这是我尝试过的一些事情

public class FeedFragment extends Fragment {

//Firebase instance variables
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference mQuestionDatabaseReference;
private ChildEventListener mChildEventListener;
private FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

尝试 1:

FirebaseRecyclerAdapter mAdapter;
public FeedFragment() {
    //empty constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    mFirebaseDatabase = FirebaseDatabase.getInstance();
    mQuestionDatabaseReference = mFirebaseDatabase.getReference();

    // Inflate the layout for this fragment
    View rootView =  inflater.inflate(R.layout.fragment_feed, container, false);

    RecyclerView recycler = (RecyclerView) rootView.findViewById(R.id.feed_view_list);
    recycler.setHasFixedSize(false);
    recycler.setLayoutManager(new LinearLayoutManager(getActivity()));

    mAdapter = new FirebaseRecyclerAdapter<DataGetter, StatsViewHolder>(DataGetter.class, 0, StatsViewHolder.class, mQuestionDatabaseReference) {
        @Override
        public void populateViewHolder(FeedViewHolder viewHolder, DataGetter feedDisplay, int position) {
            int layout = getItemViewType(position);
            if (layout == R.layout.binary_feed) {
                viewHolder.setQuestionTextBin(textDisplay.getQuestionText());
                viewHolder.setbOption1(textDisplay.getOption1());
                viewHolder.setbOption2(textDisplay.getOption2());
            }
            else if (layout == R.layout.rating_feed) {
                viewHolder.setQuestionTextRat(textDisplay.getQuestionText());
            } 
            else {
                viewHolder.setQuestionTextMul(textDisplay.getQuestionText());
                viewHolder.setmOption1(textDisplay.getOption1());
                viewHolder.setmOption2(textDisplay.getOption2());
                viewHolder.setmOption3(textDisplay.getOption3());
                if (textDisplay.getNoOfOptions() >= 4) {
                    viewHolder.setmOption4(textDisplay.getOption4());
                }
                if (textDisplay.getNoOfOptions() == 5) {
                    viewHolder.setmOption5(textDisplay.getOption5());
                }
            }
        }

        @Override
        public int getItemViewType(int position)
        {
            int view;
            if(getItem(position).getQuestionType() == MainActivity.BINARY){
                view = R.layout.binary_feed;
            }
            else if(getItem(position).getQuestionType() == MainActivity.RATING) {
                view = R.layout.rating_feed;
            }
            else //if(getItem(position).getQuestionType() == MainActivity.MULTIPLE)
            {
                view = R.layout.multiple_feed;
            }
            return view;
        }
    };
    recycler.setAdapter(mAdapter);

    return rootView;
}

@Override
public void onDestroy()
{
    super.onDestroy();
    mAdapter.cleanup();
}

尝试 2:

FirebaseIndexRecyclerAdapter mAdapter;

public FeedFragment() {
    // empty constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    mFirebaseDatabase = FirebaseDatabase.getInstance();
    mQuestionDatabaseReference = mFirebaseDatabase.getReference();

    // Inflate the layout for this fragment
    View rootView = inflater.inflate(R.layout.fragment_feed, container, false);

    RecyclerView recycler = (RecyclerView) rootView.findViewById(R.id.feed_view_list);
    recycler.setHasFixedSize(false);
    recycler.setLayoutManager(new LinearLayoutManager(getActivity()));

    //attempt -> from Firebase documentation, loop over all data
    final Query feedQuery = mQuestionDatabaseReference;

    ArrayList<DataSnapshot> feedListData = new ArrayList<DataSnapshot>();

    feedQuery.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            int i = 0;
            for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
                ArrayList.add(postSnapshot);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            // Getting Post failed, log a message
            Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
            // ...
        }
    });

    mAdapter = new FirebaseIndexRecyclerAdapter<DataGetter, FeedViewHolder>(DataGetter.class, 0, FeedViewHolder.class,
            feedQuery,mQuestionDatabaseReference) {
            //remaining code is same as attempt 1
    }

【问题讨论】:

  • Firebase 数据库 API 无法根据其值排除特定节点。见stackoverflow.com/a/39195551/209103
  • 哦,好的。谢谢你@FrankvanPuffelen。但是有没有办法完成第一部分,即按照问题中的说明读取所有数据?
  • 您可以从数据库中的任何位置读取。因此,如果您想要特定用户的密钥,请阅读/app_home/$uid。如果您想阅读所有用户,您将阅读/app_home,然后遍历用户。见firebase.google.com/docs/database/web/…
  • @FrankvanPuffelen 1)使用您建议的方法,我以某种方式最终读取了数据键而不是存储在这些键中的数据(例如,读取 KI-7Xt1sXXDEAycabo5 而不是 option1 的值)。您能否发送一些代码来展示如何通过循环实际执行读取? 2)只是好奇。有没有办法使用 FirebaseUI 的一部分 FirebaseIndexListAdapter 来完成上述操作?如果是,如何初始化 keyRef 和 dataRef?参考这个:github.com/firebase/FirebaseUI-Android/tree/master/database.
  • 在 Firebase 中,您可以为要在应用中显示的内容建模数据。因此,如果您想显示某事物的列表,请在数据库中为这些事物的列表建模。如果您需要显示用户列表,请存储用户列表。如果您需要显示问题列表,请存储问题列表。

标签: android android-studio firebase firebase-realtime-database


【解决方案1】:

在上面的代码中,在 postSnapshot 中添加 ValueAddedListener 会将值设置为 Ki-7Xt 等键。添加另一个循环以遍历 postSnapshot.getChildren() 将提供必要的“内部数据”。

//a custom adapter extended from ArrayAdapter
FeedAdapter feedAdapter;
feedQuery.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            int i = 0;
            for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
                /*One way to exclude some data is to ignore it whenever it
                 *appears and take action for the others. The same approach 
                 *has been taken here in the if condition*/
                if(postSnapshot.getKey().compareTo(user.getUid())!=0) {
                    //The inner loop to read data from the final desired location
                    for (DataSnapshot data : postSnapshot.getChildren()) {
                        DataGetter dataGetter = data.getValue(DataGetter.class);
                        //adding incoming data to adapter
                        feedAdapter.add(dataGetter);
                    }
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            //Getting values failed
            Log.i(TAG, "loadPost:onCancelled", databaseError.toException());
            //...
        }
    });

感谢@FrankvanPuffelen 在您最近 2 个 cmets 中给出的解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多