使用Firebase按键获取元素

时间:2017-03-07 13:54:31

标签: android firebase firebase-realtime-database

我一直在尝试使用其密钥从Firebase数据库中检索元素。我有一个用户类,用户在数据库中。

1

我想使用此方法使用其键检索对象用户:

public User getConnectedUserByUId(final String uid){
    DatabaseReference database = FirebaseDatabase.getInstance().getReference();
    DatabaseReference ref = database.child("users");
    final List<User> connectedUser= new ArrayList<User>();
    ref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot item: dataSnapshot.getChildren()) {
                if (item.getKey()==uid)
                {
                    User user= dataSnapshot.getValue(User.class);
                    connectedUser.add(user);
                }

            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });
    return connectedUser.get(0);
}

但每次都会返回一个空列表。

4 个答案:

答案 0 :(得分:2)

问题在于:

if (item.getKey()==uid)

因为您要比较java 中的2 String,所以必须使用方法 string.equals(Object other)不是==运营商。

此外,由于您知道Firebase中数据的密钥,因此您可以使用它来获取引用而无需循环所有子项。
类似的东西:

DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = database.child("users").child(uid);

答案 1 :(得分:0)

在这里,您尝试仅在更改的数据上检查非常具体的ID。相反,请尝试使用filterByKey的Firebase查询,而不是使用自己的函数来实现这一点。这是我尝试替换您的函数的示例代码:

DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = database.child("users");
Query connectedUser = ref.equalTo(uid);
connectedUser.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
            // TODO: handle the post here
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
        // ...
    }
});

根据Firebase文档中的说明:https://firebase.google.com/docs/database/android/lists-of-data#filtering_data

答案 2 :(得分:0)

行:User user= dataSnapshot.getValue(User.class); 你必须把:User user= item.getValue(User.class); 并且在得到用户之后你必须检查id:

if (user.getKey()==uid){
connectedUser.add(user);
}

答案 3 :(得分:0)

有2个错误和一个小问题:

  • 您正在使用==来比较两个String个对象。在java中,只有它们是相同的引用时才是真的。请改用equals
  • addValueEventListener只添加一个在添加后调用的侦听器,然后每次在您正在侦听的值发生更改时:这是异步行为。您正试图同步获取数据。请阅读有关此事的内容。
  • 你正在获取无用的数据:你只需要一个对象,但你需要获取大量的数据。请考虑使用最接近的参考来获取您正在获取的数据。

总而言之,这里有一些代码。我现在要指出,强制同步获取自然异步数据是一种不好的做法。不过,这是一个解决方案:

public User getConnectedUserByUId(final String uid){
    DatabaseReference database = FirebaseDatabase.getInstance().getReference();
    DatabaseReference ref = database.child("users").child(uid);
    Semaphore sem = new Semaphore(0);
    User[] array = new User[1];
    ref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot item: dataSnapshot.getChildren()) {
                if (item.getKey()==uid)
                {
                    User user= dataSnapshot.getValue(User.class);
                    array[0] = user;
                }

            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });
    try
        {
        sem.tryAcquire(10, TimeUnit.SECONDS);
        }
    catch (Exception ignored)
        {
        }
    return array[0];
}
编辑:我刚刚看到这篇文章很老了。我不确定我是怎么来到这里的。