【问题标题】:How to properly retrieve value from Firebase Realtime Database?如何从 Firebase 实时数据库中正确检索值?
【发布时间】:2017-07-03 15:15:30
【问题描述】:

我有以下数据结构:

see here

name 可以有无限数量的孩子。

以及下面的代码:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();    
DatabaseReference dirFire = rootRef.child("messages").child("name");

 dirFire.addListenerForSingleValueEvent(new ValueEventListener() {
 @Override
 public void onDataChange(DataSnapshot dataSnapshot) {
    String name = dataSnapshot.getValue(String.class);
    //do what you want with the name
 }

 @Override
 public void onCancelled(DatabaseError databaseError) {

 }
 });

使用上面的代码,我无法检索name 的值。如果客户端不知道key,我如何检索name

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    请使用此代码:

    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();    
    DatabaseReference messagesRef = rootRef.child("messages");
    ValueEventListener eventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot ds : dataSnapshot.getChildren()) {
                String key = ds.getKey();
    
                DatabaseReference keyRef = rootRef.child("messages").child(key).child("name");
                ValueEventListener valueEventListener = new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        for (DataSnapshot ds1 : dataSnapshot.getChildren()) {
                            String name = ds1.getValue(String.class);
                            Log.d("TAG", name);
                        }
                    }
    
                    @Override
                    public void onCancelled(DatabaseError databaseError) {}
                };
                keyRef.addListenerForSingleValueEvent(valueEventListener);
            }
        }
    
        @Override
        public void onCancelled(DatabaseError databaseError) {}
    };
    messagesRef.addListenerForSingleValueEvent(eventListener);
    

    编辑:这是另一种使用类似于早期解决方案的方法。

    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();    
    DatabaseReference messagesRef = rootRef.child("messages");
    ValueEventListener eventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot ds : dataSnapshot.getChildren()) {
                for (DataSnapshot nameSnapshot : ds.child("name").getChildren()) {
                    String name = nameSnapshot.getValue(String.class);
                    Log.d("TAG", name);
                }
            }
        }
    
        @Override
        public void onCancelled(DatabaseError databaseError) {}
    };
    messagesRef.addListenerForSingleValueEvent(eventListener);
    

    输出将是:

    John Miche
    Joe Mitch
    Sabr. A
    Luis Jean
    

    【讨论】:

    • 感谢您的回答。但是,就我而言,name 有很多孩子,所以这行不通。可以调整一下代码吗?
    • 我会给你写一些代码,但我也需要看看其他孩子。
    • 我更新了问题。请注意,name 可能有多个不同的子级。
    • 不可能,因为 Firebase 数据库的结构是一对键和值。您只有在 Firebase 中允许使用的密钥。请给我们一个真实的截图。
    • 我认为您在循环中进行了不必要的查询,您已经下载了所有数据。
    【解决方案2】:

    将您的数据获取到 hashMap..

      FirebaseDatabase.getInstance().getReference()
                .child("messages")
                .addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot rootSnapshot) {
                        if (rootSnapshot.exists()) {
                            final Map<String, Map<String, String>> messageNameMap = new HashMap<>();
                            for (DataSnapshot messageSnapshot : rootSnapshot.getChildren()) {
                                final String messageKey = messageSnapshot.getKey();
                                HashMap<String, String> nameMap = new HashMap<String, String>();
                                if (messageSnapshot.child("name").exists()) {
                                    for (DataSnapshot nameSnapshot : messageSnapshot.child("name").getChildren()) {
                                        final String nameKey = nameSnapshot.getKey();
                                        final String nameValue = nameSnapshot.getValue(String.class);
                                        nameMap.put(nameKey, nameValue);
                                    }
                                }
                                if (!nameMap.isEmpty()) {
                                    messageNameMap.put(messageKey, nameMap);
                                }
                            }
    
                            if (!messageNameMap.isEmpty()) {
                                // Here messageNameMap contains your data as such
    
                                // key: -Ko8bLawP4... val: Map Containing: 
                                //                          key: -Ko8wk... val: Jonathan Smith
                                //                          key: -Ko8wk... val: Kapler Moe
                            }
                        }
                    }
    
                    @Override
                    public void onCancelled(DatabaseError databaseError) {
    
                    }
                });
    

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 2018-09-11
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      • 1970-01-01
      相关资源
      最近更新 更多