首页 > 解决方案 > 通过数据库快照检索孩子列表

问题描述

通过查询检索子节点有点麻烦。

这是我的数据结构:

Firebase 结构

我设法能够使用上图中突出显示的“1”节点成功查询和检索数据。这是我的代码:

databaseRecipes = FirebaseDatabase.getInstance().getReference().child("recipe");

Query query = databaseRecipes.orderByChild(userId).equalTo(true);

query.addListenerForSingleValueEvent(new ValueEventListener()
    {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot)
        {
            if(dataSnapshot.exists())
            {
                Toast.makeText(getApplicationContext(), "Results found!", Toast.LENGTH_LONG).show();

                arrayList.clear();
                for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren())
                {
                    Recipe recipe = dataSnapshot1.getValue(Recipe.class);
                    arrayList.add(recipe);
                }

                final RecipeAdapter recipeAdapter = new RecipeAdapter(getApplicationContext(), arrayList);
                recyclerView.setAdapter(recipeAdapter);
                recipeAdapter.notifyDataSetChanged();
            }
            else
            {
               // Toast.makeText(getApplicationContext(), "No retreivable results :(", Toast.LENGTH_LONG).show();
                Toast.makeText(getApplicationContext(), userId, Toast.LENGTH_LONG).show();
            }
        }

但是,我宁愿将所有“收藏夹”放在它们自己的单独节点下,如用“2”突出显示的那样。(那里只有一个孩子用于测试目的,实际上会节省更多,所以这样做会更整洁。)

使用此代码:

Query query = databaseRecipes.child("favourite").orderByChild(userId).equalTo(true);

我还尝试将引用更改为:

databaseRecipes = FirebaseDatabase.getInstance().getReference().child("recipe").child("favourite");

并查询:

Query query = databaseRecipes.orderByChild(userId).equalTo(true);

但无论哪种方式都不会检索到任何结果。我认为我的问题是从以下方面要求孩子DataSnapshot

for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) 

但是我整天都在兜圈子,试图找到一个替代方案(我想我错过了一些非常简单的东西——这更烦人!),所以任何帮助都将不胜感激。

提前为我糟糕的绘画技巧道歉!

编辑

如果其他人从 SQL 背景中遇到这个 Firebase 新手,Alex 给出了可靠的建议。

创建的新节点:

新的数据结构

查询节点的代码 -

数据库参考:

databaseFvourites = FirebaseDatabase.getInstance().getReference().child("favouriteRecipes").child(userId);

询问:

 Query query = databaseFvourites.orderByChild(userId).equalTo(true);

数据结构可能会进一步改进,但根据我的需要,它可以很好地完成工作。

标签: javaandroidfirebasefirebase-realtime-database

解决方案


When you are using the following query:

Query query = databaseRecipes.orderByChild(userId).equalTo(true);

Everything works fine because your uid is a property within your -LY18 ... hFqO object.

The following query:

Query query = databaseRecipes.child("favourite").orderByChild(userId).equalTo(true);

Won't work since you are missing a child, which is the actual pushed id -LY18 ... hFqO.

I think you are looking for a query that might look like this:

databaseRecipes.child($uid).child("favourite").orderByChild(userId).equalTo(true);

But unfortunately there are no wildcards in Firebase. So you cannot filter items based on a property that exists within a map. This is actually possible in Cloud Firestore but regarding your use-case, you should consider augmenting your data structure to allow a reverse lookup by creating another node named favoriteUsers in which you should add all favorite user recipes. This practice is called denormalization and is a common practice when it comes to Firebase. If you are new to NoQSL databases, I recommend you see this video, Denormalization is normal with the Firebase Database for a better understanding.

Also, when you are duplicating data, there is one thing that need to keep in mind. In the same way you are adding data, you need to maintain it. With other words, if you want to update/detele an item, you need to do it in every place that it exists.


推荐阅读