首先,我知道这个问题已被多次询问,但最近我的应用程序出现问题引起了我对此事的兴趣。我也阅读了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()
返回null。然后,这就是我突然想要一个解释,以便向前推进,我可以更好地理解这两个听众是如何工作和选择的。
这些是我的具体问题:
感谢您阅读本部分,如果这个问题太长,我会道歉。
答案 0 :(得分:2)
它更加简单:ValueEventListener
一次性触发整个结果,ChildEventListener
分别触发结果的每个子节点。< / p>
要确定您是需要ValueEventListener
还是ChildEventListener
,需要考虑以下两点:
如果您有一个指向单个项目的听众,则您将使用ValueEventListener
。
如果您有一个指向列表的侦听器或查询,无论是否只有一个子/结果,您都需要处理该列表。您可以使用ChildEventListener
或循环DataSnapshot.getChildren()
中的ValueEventListener.onDataChange()
来完成此操作。
答案 1 :(得分:1)
这些是我的具体问题:
如果涉及查询,ChildEventListener是我选择的那个而不是替代方案吗?
从上面的两个例子中,我可以使用ValueEventListener来指定具有Key:Value对的节点,该节点紧跟指定节点下一层。另一方面,当没有涉及Value时使用ChildEventListener,只是Childs(ChildEventListener中的“Child”是什么意思?)。我之前的发言是否正确?
valueeventlistener和childeventlistener都有点相同,但它们只与只读取一次数据的addListenerForSingleValueEvent
不同。
现在,如果涉及查询,你不能选择其中任何一个,你不必总是使用childeventListener
。
对于第二个问题,你说的有点真实,通常在我们用于循环的valueeventlistener
中:
for(DataSnapshot data : dataSnapshot.getChildren()){
因此数据将在dataSnapshot的子节点内迭代。但是如果你使用ChildEventListener
,你就不必在上面使用它。
但显然如果嵌套的更多,你必须在childeventlistener