经过几天的实验,我解决了这个问题。
重点是,
我惊讶地发现即使查询也可以按深度嵌套排序
孩子,但它只适用于孩子 ONE 更高级别!
在这种情况下,我尝试先向下一层节点,并在其上查询特定时间段,它可以工作。
这是我在 Firebase 实时数据库上的数据树:
为了读取存储在 Firebase 中的 POJO 模型,我设置了一个辅助类来为我服务。
所以我运行FirebaseDatabaseHelper.getInstance().readCatalogFromDatabase(Card.class, listener, start, end); 同时用最新的数据库更新我的用户界面。
关于我的 FirebaseDatabaseHelper,有两种相关方法可以很好地帮助我读取数据库 reference() 上的模型,它指的是包含许多模型的父节点,例如“/Card/user_id”节点,其中包含一堆子节点,表示卡片详细信息在 /Card/user_id/card_id”。
/**
* attaches listener to obtain values at child locations of "catalog/" storing lots of models in JSON tree
* reads values created in a specific period and ordered by date
*
* catalog: "Card" for card
* "Comment" for comment
*
* It's surprised to found out even query can be ordered by deep nested children, but children ONE more level down only
* Being such circumstance, go for node one more level down first and do query for a specific period on it
*/
public void readCatalogFromDatabase(final Class<?> clazz, final OnReadDatabaseChildEventListener child_listener, final long start, final long end) {
//Logger.d(">>> end at date before:" + (end/(1*24*60*60*1000) - start/(1*24*60*60*1000)));
Logger.d(">>> start:" + start + ", end:" + end);
DatabaseReference referenceCatalog;
OnReadDatabaseValueEventListener ids_listener;
String catalog;
if (clazz.getName().equals(Card.class.getName())) {
ids_listener = new OnReadDatabaseValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> ids = new LinkedList<>();
Logger.d("... user count:" + dataSnapshot.getChildrenCount());
/**
* $ROOT/catalog/user_id/CardId/CardId
* $ROOT/catalog/user_id/CardId/ProfilePhoto
* $ROOT/catalog/user_id/CardId/ProfileTitle
* $ROOT/catalog/user_id/CardId/ProfileName
* $ROOT/catalog/user_id/CardId/ProfileID
* $ROOT/catalog/user_id/CardId/ArticleTitle
* $ROOT/catalog/user_id/CardId/ArticleContent
* $ROOT/catalog/user_id/CardId/ArticleCount
* $ROOT/catalog/user_id/CardId/ArticlePhoto
* $ROOT/catalog/user_id/CardId/ArticlePhotoFileName
* $ROOT/catalog/user_id/CardId/Distance
* $ROOT/catalog/user_id/CardId/Date
* ^[key] :[value] -> initial
* ^[key] :[value] -> 1th for-loop
*/
for (DataSnapshot snapShotOfUserId : dataSnapshot.getChildren()) {
Logger.d("... user(" + snapShotOfUserId.getKey() + ") post count:" + snapShotOfUserId.getChildrenCount());
ids.add(snapShotOfUserId.getKey());
}
for (String id : ids) readListFromDatabase(clazz, id, child_listener, start, end);
FirebaseDatabaseHelper.getInstance().detachValueEventListener(this);
}
@Override
public void onCancelled(DatabaseError databaseError) {
child_listener.onCancelled(databaseError);
FirebaseDatabaseHelper.getInstance().detachValueEventListener(this);
}
};
catalog = Card.class.getSimpleName();
referenceCatalog = getDatabaseChild(catalog, null, null);
referenceCatalog.orderByKey().limitToLast(COUNT_ON_PAGE).addListenerForSingleValueEvent(ids_listener);
mValueEventListeners.put(ids_listener, referenceCatalog);
} else if (clazz.getName().equals(Comment.class.getName())) {
ids_listener = new OnReadDatabaseValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> ids = new LinkedList<>();
Logger.d("... card count:" + dataSnapshot.getChildrenCount());
/**
* $ROOT/catalog/card_id/CommentId/CardId
* $ROOT/catalog/card_id/CommentId/CommentId
* $ROOT/catalog/card_id/CommentId/ProfilePhoto
* $ROOT/catalog/card_id/CommentId/ProfileName
* $ROOT/catalog/card_id/CommentId/ProfileID
* $ROOT/catalog/card_id/CommentId/Comment
* $ROOT/catalog/card_id/CommentId/Distance
* $ROOT/catalog/card_id/CommentId/Date
* ^[key] :[value] -> initial
* ^[key] :[value] -> 1th for-loop
*/
for (DataSnapshot snapShotOfCardId : dataSnapshot.getChildren()) {
Logger.d("... card(" + snapShotOfCardId.getKey() + ") comment count:" + snapShotOfCardId.getChildrenCount());
ids.add(snapShotOfCardId.getKey());
}
for (String id : ids) readListFromDatabase(clazz, id, child_listener, start, end);
FirebaseDatabaseHelper.getInstance().detachValueEventListener(this);
}
@Override
public void onCancelled(DatabaseError databaseError) {
child_listener.onCancelled(databaseError);
FirebaseDatabaseHelper.getInstance().detachValueEventListener(this);
}
};
catalog = Comment.class.getSimpleName();
referenceCatalog = getDatabaseChild(catalog, null, null);
referenceCatalog.orderByKey().limitToLast(COUNT_ON_PAGE).addListenerForSingleValueEvent(ids_listener);
mValueEventListeners.put(ids_listener, referenceCatalog);
}
然后去,
/**
* attaches listener to obtain values at child locations of "catalog/id/" storing list of models in JSON tree
* reads values created in a specific period and ordered by date
*
* id: user id for card
* card id for comment
*
* query can be ordered by deep nested ONE more level down children
*/
public void readListFromDatabase(Class<?> clazz, String id, OnReadDatabaseChildEventListener listener, long start, long end) {
//Logger.d(">>> end at date before:" + (end/(1*24*60*60*1000) - start/(1*24*60*60*1000)));
Logger.d(">>> start:" + start + ", end:" + end + ", id:" + id);
DatabaseReference referenceCatalog;
Query query;
String catalog;
if (clazz.getName().equals(Card.class.getName())) {
catalog = Card.class.getSimpleName();
referenceCatalog = getDatabaseChild(catalog, id, null);
query = referenceCatalog.orderByChild("Date").startAt(start).endAt(end).limitToLast(COUNT_ON_PAGE);
query.addChildEventListener(listener);
mChildEventListeners.put(listener, referenceCatalog);
} else if (clazz.getName().equals(Comment.class.getName())) {
catalog = Comment.class.getSimpleName();
referenceCatalog = getDatabaseChild(catalog, id, null);
query = referenceCatalog.orderByChild("Date").startAt(start).endAt(end).limitToLast(COUNT_ON_PAGE);
query.addChildEventListener(listener);
mChildEventListeners.put(listener, referenceCatalog);
}
}
关于数据库参考,
/**
* gets a database reference to location headed with "/catalog/", "/id/" and "/key/" as prefixes(to a child location in JSON tree)
*
* id: user id for card
* card id for comment
* key:
* card id for card
* comment id for comment
*/
private DatabaseReference getDatabaseChild(String catalog, String id, String key) {
Logger.d(">>>");
DatabaseReference reference;
if (catalog == null) {
if (id == null) {
if (key == null) {
Logger.d("... catalog:" + catalog + ", id:" + id + ", key:" + key);
reference = FirebaseDatabase.getInstance().getReference();
} else {
Logger.d("... catalog:" + catalog + ", id:" + id + ", key:" + key);
reference = FirebaseDatabase.getInstance().getReference(key);
}
} else {
if (key == null) {
Logger.d("... catalog:" + catalog + ", id:" + id + ", key:" + key);
reference = FirebaseDatabase.getInstance().getReference(id);
} else {
Logger.d("... catalog:" + catalog + ", id:" + id + ", key:" + key);
reference = FirebaseDatabase.getInstance().getReference(id + "/" + key);
}
}
} else {
if (id == null) {
if (key == null) {
Logger.d("... catalog:" + catalog + ", id:" + id + ", key:" + key);
reference = FirebaseDatabase.getInstance().getReference(catalog);
} else {
Logger.d("... catalog:" + catalog + ", id:" + id + ", key:" + key);
reference = FirebaseDatabase.getInstance().getReference(catalog + "/" + key);
}
} else {
if (key == null) {
Logger.d("... catalog:" + catalog + ", id:" + id + ", key:" + key);
reference = FirebaseDatabase.getInstance().getReference(catalog + "/" + id);
} else {
Logger.d("... catalog:" + catalog + ", id:" + id + ", key:" + key);
reference = FirebaseDatabase.getInstance().getReference(catalog + "/" + id + "/" + key);
}
}
}
return reference;
}
这就是我在特定时期去查询的方式。
此外,我发现了一些关于人们应该打电话的答案
addChildEventListener() 关注orderByChild();然而,之后
运行实验,我说,
Query query;
query = referenceCatalog.orderByChild("Date").startAt(start).endAt(end).limitToLast(COUNT_ON_PAGE);
query.addChildEventListener(listener);
和
referenceCatalog.orderByChild("Date").startAt(start).endAt(end).limitToLast(COUNT_ON_PAGE).addChildEventListener(listener);
它们是一样的。
我认为他们的区别在于人们使用匿名 Java 编程的方式
上课与否。