如何从Firebase Android获取所有子列表


73

我想要Android中Firebase的所有子列表。

我已经实现了此代码,但无法正常工作。

mFirebaseRef = new Firebase(FIREBASE_URL);

mFirebaseRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<String> td = (ArrayList<String>) dataSnapshot.getValue();
        //notifyDataSetChanged();
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {

    }
});


2
请在下面回答。但这只是部分猜测,因为“它不起作用”非常模糊,而且您不包含数据片段。如果我的答案不能解决您的问题:您会遇到什么错误?您的数据是什么样的(它的复制/粘贴示例,没有屏幕截图,也没有描述)?
Frank van Puffelen

Answers:


97

我希望下面的代码有效

Firebase ref = new Firebase(FIREBASE_URL);

  ref.addValueEventListener(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot snapshot) {
          Log.e("Count " ,""+snapshot.getChildrenCount());
          for (DataSnapshot postSnapshot: snapshot.getChildren()) {
            <YourClass> post = postSnapshot.getValue(<YourClass>.class);
            Log.e("Get Data", post.<YourMethod>());
          }
      }
      @Override
      public void onCancelled(FirebaseError firebaseError) {
          Log.e("The read failed: " ,firebaseError.getMessage());
      }
  });

5
当我打印日志时,它为null。你可以帮帮我吗?
Rethinavel '16

5
不要忘了使用addListenerForSingleValueEvent(),而不是addValueEventListener()如果你只需要一次数据。
塞巴斯蒂安

35

Firebase以这种格式存储值序列:

"-K-Y_Rhyxy9kfzIWw7Jq": "Value 1"
"-K-Y_RqDV_zbNLPJYnOA": "Value 2"
"-K-Y_SBoKvx6gAabUPDK": "Value 3"

如果那是您的方式,那么您输入的类型错误。上面的结构表示为Map,而不是List

mFirebaseRef = new Firebase(FIREBASE_URL);

mFirebaseRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();

        List<Object> values = td.values();

        //notifyDataSetChanged();
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {

    }
});

我想要“ -K-Y_Rhyxy9kfzIWw7Jq”的父级列表:“值1”“-K-Y_RqDV_zbNLPJYnOA”:“值2”“-K-Y_SBoKvx6gAabUPDK”:“值3”
Parth Vyas

可以吗?Map<String, MyDataObject> = (HashMap<String, MyDataObject>) dataSnapshot.getValue();还是必须将Object转换为MyDataObject?
Vinay Nagaraj

@Frank,机器人工作室是显示红色下划线此线路列表<对象>值= td.values(); ...错误: -不能施放集合对象到列表中堆栈跟踪误差object..throwing ..
纳伦德拉Baratam '16

@弗兰克谢谢,List<Object> values = td.values();很高兴知道。
Mtl Dev 2016年

8
@NarendraBaratam我有同样的问题。请改用这种方式:List<Object> values = new Arraylist<>(td.values());
Hesam,2016年

27
FirebaseDatabase mFirebaseDatabase = FirebaseDatabase.getInstance();
 DatabaseReference databaseReference =    mFirebaseDatabase.getReference(FIREBASE_URL);
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                    Log.v(TAG,""+ childDataSnapshot.getKey()); //displays the key for the node
                    Log.v(TAG,""+ childDataSnapshot.child(--ENTER THE KEY NAME eg. firstname or email etc.--).getValue());   //gives the value for given keyname
                }
            }
        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

希望能帮助到你!


13

正如Frank所说,Firebase"key": "Value"Map结构存储格式的值序列

要从此序列中获取列表,您必须

  1. 初始化GenericTypeIndicatorHashMap中字符串和你的对象
  2. DataSnapShot的值作为GenericTypeIndicator获取Map中
  3. 使用HashMap值初始化ArrayList

GenericTypeIndicator<HashMap<String, Object>> objectsGTypeInd = new GenericTypeIndicator<HashMap<String, Object>>() {};
Map<String, Object> objectHashMap = dataSnapShot.getValue(objectsGTypeInd);
ArrayList<Object> objectArrayList = new ArrayList<Object>(objectHashMap.values());

对我来说效果很好,希望对您有所帮助。



11

我做了这样的事情:

Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {

@Override
public void onDataChange(DataSnapshot snapshot) {
    Map<String, Object> objectMap = (HashMap<String, Object>)    
             dataSnapshot.getValue();
    List<Match> = new ArrayList<Match>();
    for (Object obj : objectMap.values()) {
        if (obj instanceof Map) {
            Map<String, Object> mapObj = (Map<String, Object>) obj;
            Match match = new Match();
            match.setSport((String) mapObj.get(Constants.SPORT));
            match.setPlayingWith((String) mapObj.get(Constants.PLAYER));
            list.add(match);
        }
    }
  }
  @Override
  public void onCancelled(FirebaseError firebaseError) {

  }
});

1
我理解正确吗?即使您只添加一个Match type值,您还是每次循环吗?
MeLine 2016年

6

就我而言,只有给定的解决方案可以正常工作。

Firebase ArrayList结构的屏幕截图:

在此处输入图片说明

如何从DataSnapshotFirebase获取整个列表

GenericTypeIndicator<Map<String, List<Education>>> genericTypeIndicator = new GenericTypeIndicator<Map<String, List<Education>>>() {};
Map<String, List<Education>> hashMap = dataSnapshot.getValue(genericTypeIndicator);

for (Map.Entry<String,List<Education>> entry : hashMap.entrySet()) {
      List<Education> educations = entry.getValue();
        for (Education education: educations){
             Log.i(TAG, education.Degree);
         }
}

Education.java :(模型类)。

public class Education implements Serializable{

    public String Degree;
    public String Result;
}

希望这会很好。


6
    @Override
       public void onDataChange(DataSnapshot dataSnapshot) {
           for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
               User user = postSnapshot.getValue(User.class);
               list.add(user);
           }
           for (int i=0;i<list.size();i++)
           {
               Log.e("Name",list.get(i).getname());
               Log.e("Phone",list.get(i).getphone());

           }
       }
       @Override
       public void onCancelled(FirebaseError firebaseError) {
       Log.e("error",firebaseError.getMessage());
       }
   });

类模型

class User{

String name;

String phone;

public String getname() {
    return name;
}

public void setname(String name) {
    this.name = name;
}


public String getphone() {
    return phone;
}

public void setphone(String phone) {
    this.phone = phone;
}
}

列表绑定

List<User> list= new ArrayList <>();

这个为你工作


5

从Firebase保存和检索数据到- (不推荐使用2.4.2版)

Firebase fb_parent = new Firebase("YOUR-FIREBASE-URL/");
Firebase fb_to_read = fb_parent.child("students/names");
Firebase fb_put_child = fb_to_read.push(); // REMEMBER THIS FOR PUSH METHOD

//INSERT DATA TO STUDENT - NAMES  I Use Push Method
fb_put_child.setValue("Zacharia"); //OR fb_put_child.setValue(YOUR MODEL) 
fb_put_child.setValue("Joseph"); //OR fb_put_child.setValue(YOUR MODEL) 
fb_put_child.setValue("bla blaaa"); //OR fb_put_child.setValue(YOUR MODEL) 

//GET DATA FROM FIREBASE INTO ARRAYLIST
fb_to_read.addValuesEventListener....{
    public void onDataChange(DataSnapshot result){
        List<String> lst = new ArrayList<String>(); // Result will be holded Here
        for(DataSnapshot dsp : result.getChildren()){
            lst.add(String.valueOf(dsp.getKey())); //add result into array list
        }
        //NOW YOU HAVE ARRAYLIST WHICH HOLD RESULTS




for(String data:lst){ 
         Toast.make(context,data,Toast.LONG_LENGTH).show; 
       }
    }
}

4

如果您使用Kotlin,那么下一个是一个很好的解决方案:

myRef.addListenerForSingleValueEvent(object : ValueEventListener {
  override fun onDataChange(dataSnapshot: DataSnapshot) {
      val list = dataSnapshot.children.map { it.getValue(YourClass::class.java)!! }
      Log.d("TAG", "Value is: $list")
}

3

奇迹般有效

final DatabaseReference senderDb = FirebaseDatabase.getInstance().getReference(Constant.NODE_MESSAGE).child(myId + "_" + otherId);

    senderDb.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();

            for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                DatabaseReference objRef = senderDb.child( childDataSnapshot.getKey());
                Map<String,Object> taskMap = new HashMap<String,Object>();
                taskMap.put("is_read", "1");
                objRef.updateChildren(taskMap); //should I use setValue()...?
                Log.v("Testing",""+ childDataSnapshot.getKey()); //displays the key for the node
            }

            //notifyDataSetChanged();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });

1
mDatabase.child("token").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
              for (DataSnapshot snapshot:dataSnapshot.getChildren())
              {
                 String key= snapshot.getKey();
                 String value=snapshot.getValue().toString();
              }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Toast.makeText(ListUser.this,databaseError.toString(),Toast.LENGTH_SHORT).show();
            }
        });

仅在孩子没有的情况下工作 SubChild

在此处输入图片说明


0

您需要编写一个自定义反序列化器,然后对其进行循环并获取hasmap的值。

自定义反序列化器:-

public class UserDetailsDeserializer implements JsonDeserializer<AllUserDetailsKeyModel> {
  /*
    bebebejunskjd:{
      "email": "akhilbv1@gmail.com",
          "mobileNum": "12345678",
          "password": "1234567",
          "username": "akhil"}*/
  @Override public AllUserDetailsKeyModel deserialize(JsonElement json, Type typeOfT,
      JsonDeserializationContext context) throws JsonParseException {

    final JsonObject jsonObject = json.getAsJsonObject();

    Gson gson = new Gson();

    Type AllUserDetailsResponseModel =
        new TypeToken<HashMap<String, AllUserDetailsResponseModel>>(){}.getType();

    HashMap<String, AllUserDetailsResponseModel> user =
        gson.fromJson(jsonObject, AllUserDetailsResponseModel);
    AllUserDetailsKeyModel result = new AllUserDetailsKeyModel();
    result.setResult(user);
    return result;
  }


}

注释中的代码是我的对象模型,您应该用模型类替换AllUserDetailsKeyModel,并将其添加到其余客户端,如下所示:-

private Converter.Factory createGsonConverter() {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(AllUserDetailsKeyModel.class, new UserDetailsDeserializer());
    Gson gson = gsonBuilder.create();
    return GsonConverterFactory.create(gson);
  }

这是改装的自定义转换器。

在您的onResponse中,您仅循环使用hasmaps并通过键获取值,而我的模型类如下所示:-

public class AllUserDetailsKeyModel {

  private Map<String, AllUserDetailsResponseModel> result;

  public Map<String, AllUserDetailsResponseModel> getResult() {
    return result;
  }

  public void setResult(Map<String, AllUserDetailsResponseModel> result) {
    this.result = result;
  }

}

可能您需要提供一个Type T,其中T是您的数据类型,而我的模型仅由一个hashmap以及为此的getter和setter组成。

最后将“自定义转换器”设置为如下所示: .addConverterFactory(createGsonConverter())

让我知道是否需要更多说明。


0

使用GenericTypeIndicator从Firebase ArrayList结构化数据库获取子节点列表

   //Start of Code
   Firebase ref = new Firebase(FIREBASE_URL);
   ref.addValueEventListener(new ValueEventListener(){
      @Override
      public void onDataChange(DataSnapshot snapshot){
         GenericTypeIndicator<List<YourClassName>> t = new GenericTypeIndicator<List<YourClassName>>{};
         List<YourClassName> messages = snapshot.getValue(t);
         Log.d("Get Data Size", messages.size());
          }
      }
      @Override
      public void onCancelled(FirebaseError firebaseError){
          Log.e("The read failed: ",firebaseError.getMessage());
      }
   });

0

您的问题是为什么您的代码不起作用。

这是您的代码:

Firebase ref = new Firebase(FIREBASE_URL);

  ref.addValueEventListener(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot snapshot) {
          Log.e("Count " ,""+snapshot.getChildrenCount());
          for (DataSnapshot postSnapshot: snapshot.getChildren()) {
            <YourClass> post = postSnapshot.getValue(<YourClass>.class);
            Log.e("Get Data", post.<YourMethod>());
          }
      }
      @Override
      public void onCancelled(FirebaseError firebaseError) {
          Log.e("The read failed: " ,firebaseError.getMessage());
      }
  })

您错过了最简单的事情: getChildren()

FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference reference = FirebaseAuth.getInstance().getReference("Donald Trump");

reference.addValueEventListener(new ValueEventListener() {
   @Override
   public void onDataChange(DataSnapshot dataSnapshot) {

            int count = (int) dataSnapshot.getChildrenCount(); // retrieve number of childrens under Donald Trump

            String[] hairColors = new String[count];

            index = 0;
            for (DataSnapshot datas : dataSnapshot.getChildren()){

                hairColors[index] = datas.getValue(String.class);

            }
            index ++

            for (int i = 0; i < count; i++)
            Toast(MainActivity.this, "hairColors : " + hairColors[i], toast.LENGTH_SHORT).show();

            }

    }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }

    });

索引++; 必须在for(DataSnapshot datas:dataSnapshot.getChildren()){
Lotfi

0
ArrayList<String> keyList = new ArrayList<String>();
mKeyRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                String temp = childDataSnapshot.getKey();
                keyList.add(temp);
                i = keyList.size();

            }
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });

这段代码可以很好地将所有Firebase键添加到arraylist中,您可以使用Firebase值或其他静态值来执行此操作。


不鼓励仅使用代码的答案。请编辑您的答案,并添加一些单词,说明它如何解决问题和/或与其他答案的不同之处。
尼克,

0
DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference mMainMenuRef = mRootRef.child("tut_master");//main
        DatabaseReference mSubMenuRef = mMainMenuRef.child("english");//sub
        List<Tutorial>   tutorialNames=new ArrayList<>();
        mSubMenuRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                for(DataSnapshot ds : dataSnapshot.getChildren()) {
                    long id = ds.child("id").getValue(Long.class);
                    String name = ds.child("name").getValue(String.class);

                    Tutorial tut = new Tutorial();
                    tut.setTutId(id+"");
                    tut.setTutName(name);
                    tutList.add(tut);

                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }


        });

0
 private FirebaseDatabase firebaseDatabase=  FirebaseDatabase.getInstance();
    private DatabaseReference databaseReference=  firebaseDatabase.getReference();
    private DatabaseReference mChildReference= databaseReference.child("data");

  mChildReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for(DataSnapshot ds : dataSnapshot.getChildren()) {
                    User commandObject = ds.getValue(User.class);
                    Log.d("TAG", commandObject.getMsg());
                }
                Toast.makeText(MainActivity.this,dataSnapshot.toString(),Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

这将为您提供帮助,您只需创建一个包含String msg的模型类即可。


0

使用Gson是我最喜欢的解决方案。

mFirebaseRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Type StringListType = new TypeToken<List<String>>(){}.getType();
        List<String> td = new Gson().fromJson(dataSnapshot.getValue(), StringListType);
    }
});

如果您认为获取TypeToken的代码不直观。您可以编写一个类来包含所需的所有类型。因此,下次您可以快速获取这些类型。

class TypeTokens{
    static public final Type StringListType = new TypeToken<List<String>>(){}.getType();
    static public final Type StringMapType = new TypeToken<Map<String, String>>(){}.getType();
    static public final Type LongMapType = new TypeToken<Map<String, Long>>(){}.getType();
    static public final Type DateMapType = new TypeToken<Map<String, Date>>(){}.getType();
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.