所以我遵循了我认为最新的Firebase建议来构建扁平数据库,如下所示:
类别和子类别是单独的节点,其中的类别引用了子类别SubCategories的键。
然后,我希望能够基于Categories键运行查询并返回其子子类别。
我的代码基于这个(过时的)示例,这是我能找到的唯一示例 - 来自https://firebase.googleblog.com/2013/04/denormalizing-your-data-is-normal.html
var commentsRef = new Firebase("https://awesome.firebaseio-demo.com/comments");
var linkRef = new Firebase("https://awesome.firebaseio-demo.com/links");
var linkCommentsRef = linkRef.child(LINK_ID).child("comments");
linkCommentsRef.on("child_added", function(snap) {
commentsRef.child(snap.key()).once("value", function() {
// Render the comment on the link page.
));
});
并尝试将其转换为在Android上运行,并且最佳猜测替代上述示例中不再存在的方法:
final DatabaseReference subCategoriesRef = FirebaseDatabase.getInstance().getReference("users").child(user.getUid()).child("SubCategories");
DatabaseReference categoriesRef = FirebaseDatabase.getInstance().getReference("users").child(user.getUid()).child("Categories");
Query categoriesSubCategoriesRef = categoriesRef.child(EXTRA_CATEGORY_KEY).child("SubCategories");
categoriesSubCategoriesRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
subCategoriesRef.child(dataSnapshot.getKey());
subCategoriesRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Log.v("item", dataSnapshot.child("SubCategories").child("SubCategoryName").getValue().toString());
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
种类有效,但它会返回SubCategories的全部,而不仅仅是那些使用EXTRA_CATEGORY_KEY指定的类别I的子类,然后它返回作为Json对象:
DataSnapshot { key = SubCategories, value = {-KZ8aQOhk1r7tj5gjM97={
Description=, isChecked=false, ID=103, Published=1, SubCategoryName=Name1, hasExtra=false, Deleted=0, CategoryID=8},
-KZ8aQP98TujvnjAERXF={Description=, isChecked=false, ID=40, Published=1, SubCategoryName=Name2, hasExtra=false, Deleted=0, CategoryID=2},...
......等等。
首先:我的数据结构是否正确,还是我遵循了不推荐的建议?其次:我的查询有什么问题?
编辑:这是数据库的当前(不正确)完整结构。每个用户都是私人用户,他们无法与任何其他用户共享任何数据。
{
"users": {
"Uc6PJMfq5VZpT2V7EHMmmGPk0Zv2": {
"Categories": {
"-KZ8aQPi5QXrFv_RrKIh": {
"CategoryName": "",
"Constant": "",
"Deleted": 0,
"Description": "",
"ID": 1,
"Published": 1,
"Sequence": 1,
"SubCategories": {
"-KZ8aQPHbCTtveAfR_D8": true,
"-KZ8aQPHbCTtveAfR_D9": true
}
}
},
"SubCategories": {
"-KZ8aQPHbCTtveAfR_D8": {
"CategoryID": 1,
"Deleted": 0,
"Description": "",
"ID": 1,
"Published": 1,
"SubCategoryName": "",
"hasExtra": false,
"isChecked": false
},
"-KZ8aQPHbCTtveAfR_D9": {
"CategoryID": 1,
"Deleted": 0,
"Description": "",
"ID": 21,
"Published": 1,
"SubCategoryName": "",
"hasExtra": false,
"isChecked": false
}
},
"journal": {
"-KYzQOrMrEenlXobzG3d": {
"entry": "Test entry",
"entryDate": {
"date": 14,
"day": 3,
"hours": 22,
"minutes": 22,
"month": 11,
"seconds": 5,
"time": 1481754125034,
"timezoneOffset": 0,
"year": 116
},
"id": "",
"source": "journal"
}
},
"userDetails": {
"email": "",
"username": ""
}
},
"anotheruniqueuser": {
"Categories": {
},
"SubCategories": {
},
"journal": {
},
"userDetails": {
"email": "",
"username": ""
}
}
}
}
答案 0 :(得分:0)
您复制的示例代码段会侦听child_added
事件,该事件将转换为Java中的ChildEventListener.onChildAdded
。
该片段变为:
DatabaseReference categoriesRef = FirebaseDatabase.getInstance().getReference("Categories");
DatabaseReference subCategoriesRef = categoriesRef.child(user.getUid()).child("SubCategories");
DatabaseReference categoriesRef = categoriesRef.child(user.getUid()).child("Categories");
DatabaseReference categoriesSubCategoriesRef = categoriesRef.child(EXTRA_CATEGORY_KEY).child("SubCategories");
categoriesSubCategoriesRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot keySnapshot, String previousChildKey) {
subCategoriesRef.child(keySnapshot.getKey());
subCategoriesRef.addSingleValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.v("item", dataSnapshot.child("SubCategories").child("SubCategoryName").getValue().toString());
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
});
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
// ...
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
// ...
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
// ...
}
@Override
public void onCancelled(DatabaseError databaseError) {
throw dataError.toException();
}
});
一些评论:
new Firebase("https://awesome.firebaseio-demo.com/links")
,转换为FirebaseDatabase.getInstance().getReference("links")
。每个用户下都有多种类型的数据。要遵循Firebase文档中的最佳做法,请将类别的元数据(如名称,描述,数字ID等内容)与其层次结构的构建分开。
Categories
category1
name: ...
description: ...
category2
name: ...
description: ...
category3
name: ...
description: ...
Parents
category2: category1
category3: category1
Children
category1
category2: true
category3: true