Firebase数据库如何根据子值获取节点?

时间:2017-09-18 09:05:42

标签: android firebase firebase-realtime-database

实际上我想让在线用户不是整个用户列表。 这是我的数据库结构:

Users
    - Uid
        - online : true

我希望获得在线用户列表,而无需获取每个用户,然后通过检查数据快照对其进行排序。

3 个答案:

答案 0 :(得分:2)

您可以通过指定子项和值来过滤项目:

ref.orderByChild("online").equalTo(true); 

此处有更多信息:https://firebase.google.com/docs/database/android/lists-of-data

答案 1 :(得分:2)

假设Users节点是Firebase根目录的直接子节点,我使用以下代码重新命令您:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef
    .child("Users")
    .child("Uid")
    .orderByChild("online")
    .equalTo(true);
query.addListenerForSingleValueEvent(/* ... */);

编辑1:如果您没有每个用户的uid,请使用以下代码:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference usersRef = rootRef.child("Users");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String uid = ds.getKey();
            Query query = usersRef.child(uid).orderByChild("online").equalTo(true);
            query.addListenerForSingleValueEvent(/* ... */);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
usersRef.addListenerForSingleValueEvent(eventListener);

Edit2:正如您在官方文档中看到的那样,addListenerForSingleValueEvent为此位置的数据添加了一个监听器。该侦听器将使用该位置的数据值触发一次。

当您编写数据时,如果您想知道数据何时提交,您可以添加在任务完成时调用的OnCompleteListenersetValue()updateChildren()方法都采用可选的完成侦听器,在将写入提交到数据库时调用该侦听器。这是一个例子:

yourRef.setValue("I'm writing data", new Firebase.CompletionListener() {
    @Override
    public void onComplete(FirebaseError firebaseError, Firebase firebase) {
        if (firebaseError != null) {
            System.out.println("Data could not be saved. " + firebaseError.getMessage());
        } else {
        System.out.println("Data saved successfully.");
        }
    }
});

关于同步,有一种常见的方法可以检测Firebase何时完成同步给定位置的初始数据。这种方法使用了Firebase event guarantees之一:

  

值事件总是最后触发,并且保证包含在拍摄快照之前发生的任何其他事件的更新。

因此,如果您在指定位置同时拥有ValueEventListenerChildEventListener,则保证在发生所有ValueEventListener.onDataChange()次呼叫后调用onChildAdded()。< / p>

但有一点要记住: Firebase不只是加载数据。它不断地将数据从服务器同步到所有连接的客户端。因此,实际上没有任何时刻可以完全检索数据。这就是你需要删除监听器的原因,如下所述。

此外,请注意您可以随时删除侦听器。最佳做法是根据活动的生命周期将其删除。

如果您在onStart中添加了监听器,则必须在onStop中将其删除。 如果您已在onResume中添加了监听器,则必须在onPause中将其删除。 如果您已在onCreate中添加了监听器,则必须在onDestroy中将其删除。 但请记住onDestroy并不总是被调用。

databaseReference.removeEventListener(valueEventListener);

答案 2 :(得分:1)

使用此代码

ref.child('Uid')

.orderByChild( '在线')    .equalTo(真);

或使用

FirebaseDatabase.getReference("Users").child("Uid").orderByChild("online").equalTo(true);