通过数据库快照检索子级列表

时间:2019-02-16 18:27:20

标签: java android firebase firebase-realtime-database

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

这是我的数据结构:

Firebase Structure

我已经设法能够使用上图中突出显示的节点“ 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会提供可靠的建议。

已创建新节点:

New Data Structure

查询节点的代码-

数据库参考:

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

查询:

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

数据结构可能甚至可以进一步改善,但是对于我的需求来说,它做得很好。

1 个答案:

答案 0 :(得分:1)

使用以下查询时:

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

一切正常,因为您的uid-LY18 ... hFqO对象中的一个属性。

以下查询:

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

由于您缺少孩子,这是实际的推送ID -LY18 ... hFqO,因此无法正常工作。

我认为您正在寻找的查询可能如下所示:

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

但是很遗憾,Firebase中没有通配符。因此,您不能基于地图中存在的属性来过滤项目。实际上,这在Cloud Firestore中是可能的,但是对于您的用例,您应该考虑通过创建另一个名为favoriteUsers的节点来扩展数据结构以允许反向查找,并在其中添加所有喜欢的用户recipes。这种做法称为denormalization,是Firebase的常见做法。如果您不熟悉NoQSL数据库,建议您观看此视频Denormalization is normal with the Firebase Database,以更好地理解。

此外,在复制数据时,需要记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果您想更新/删除项目,则需要在它存在的每个位置进行。