首先,我知道这个问题已被问过多次,但是我的应用程序最近遇到的麻烦激起了我对此事的兴趣。而且我还阅读了Firebase文档。
What is the difference between ChildEventListener and ValueEventListener Firebase interfaces?
从上面的主题来看,Child和Event侦听器似乎具有相同的功能,但具有不同的“灵活性”,我认为这是事实。
仅出于上下文考虑,我将从最近的项目中提供两个示例。
示例1:
数据库结构
{
"requests" : {
"pushed_id_1" : {
"request_name" : "qjvnocnqjd",
"request_date" : "11 Oct 2017"
},
"pushed_id_2" : {
"request_name" : "qjvnocnqjd",
"request_date" : "10 Nov 2017"
}
}
}
参照上面的结构,我的最初计划是使用Firebase中的查询方法来获取最后一个节点的值。这是代码片段。
myRef.child("requests").orderByKey().limitToLast(1).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Request request = dataSnapshot.getValue(Request.class);
Log.d(TAG, "requestDate: " + request.getRequest_date());
}
上面的代码为我提供了
request.getRequest_date()
的空值。然后经过一番痛苦的寻找解决方案后,我发现了下面的帖子。Retrieve null values from Firebase database Android
上面链接的TL; DR解决方案是改为将ValueEventListener更改为ChildListener,并且在我的项目中起作用。接下来是第二个例子。
示例2:
数据库结构
{
"users" : {
"user_uid_1" : {
"user_name" : "Admin",
"join_date" : "7 Nov 2017"
},
"user_uid_2" : {
"user_name" : "Member",
"join_date" : "9 Nov 2017"
}
}
}
这是我的代码片段,用于获取用户数据。
myRef.child("users").child(userID).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
Log.d(TAG, "userDeets: " + user.getJoin_date());
}
}
上面的代码不会为
user.getJoin_date()
返回空值。然后,这时我突然想要一个解释,以便继续前进,我可以更好地理解这两个听众的工作方式并做出相应选择。这些是我的具体问题:
感谢您阅读本部分内容,如果这个问题过长,我深表歉意。
最佳答案
这些是我的具体问题:
如果涉及查询,ChildEventListener是我选择的替代方法吗?
从上面的两个示例中,当我可以指定具有Key:Value对的节点位于指定节点的下一层时,似乎使用了ValueEventListener。另一方面,在不涉及任何值(仅涉及Childs)的情况下,将使用ChildEventListener(这是ChildEventListener中的“Child”是什么意思?)。我可以说前面的陈述吗?
valueeventlistener和childeventlistener有点相同,但它们与addListenerForSingleValueEvent
不同,后者仅读取一次数据。
现在,如果涉及到查询,则不能选择两者中的任何一个,而不必始终使用childeventListener
。
对于第二个问题,它有点像您所说的那样,通常在valueeventlistener
中,我们使用for循环:
for(DataSnapshot data : dataSnapshot.getChildren()){
因此,数据将在dataSnapshot的子级中进行迭代。但是,如果您使用ChildEventListener
,则不必在上面的循环中使用它。但是显然,如果嵌套更多,则必须在
childeventlistener
中执行该循环