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

问题描述 投票:1回答:1

通过查询检索子节点时遇到一些麻烦。

这是我的数据结构:

我已经设法能够使用上图中突出显示为“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);

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

java android firebase firebase-realtime-database
1个回答
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以便更好地理解。

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

热门问题
推荐问题
最新问题