如何从安卓系统上的 FirebaseDataSnapshot 中提取对象列表

我想转换所有的 FirebaseDataSnapshot子列表在机器人。

就像这样:

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) {


}
});
179751 次浏览

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) {


}
});

我希望下面的代码可以工作

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());
}
});

从 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;
}
}
}

我做了这样的事:

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) {


}
});
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) {


}
});

希望能有帮助!

在我的情况下,只有给出的解决方案工作良好。

Firebase ArrayList 结构的截图:

enter image description here

如何从 火力点DataSnapshot

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: (Model class).

public class Education implements Serializable{


public String Degree;
public String Result;
}

希望这能管用。

正如弗兰克所说,火力点存储的序列值的格式为 "key": "Value" 这是一个 地图结构

从这个序列得到 名单你必须

  1. 绳子HashMap和你的 反对初始化 通用类型指示器
  2. DataSnapShot的值作为 通用类型指示器转换为 地图
  3. HashMap值初始化 数组列表

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());

我觉得挺好的,希望能有帮助。

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

enter image description here

您需要编写一个自定义的反序列化器,然后循环它并获取 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 中,只需使用 hasmap 循环并按键获取值,我的模型类如下所示:-

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 是您的数据 Type,而我的模型仅由散列表、 getter 和 setter 组成。

最后设置自定义转换器改造如下:-.addConverterFactory(createGsonConverter())

如果你需要进一步澄清,请告诉我。

使用 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());
}
});

像魔法一样有效

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) {


}


});

你的问题是为什么你的代码不能工作。

这是你的密码:

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) {


}


});
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 键添加到数组列表中,您可以使用 firebase 值或其他静态值。

    @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 <>();

这对你有好处

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) {


}




});
 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) {


}
});

这将对您有所帮助,您只需创建一个包含 Stringmsg 的模型类。

使用 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();
}

如果你使用 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")
}

这是我的2美分贡献(在 Kotlin) :

    private fun getData(childUid:String) {
    

refDB = firebaseDB.reference.child(MAIN_DATABASE_FOLDER).child(childUid)
if(childEventDataListener == null) {
childEventDataListener = object : ChildEventListener {
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
                

for(snap in snapshot.children) {
val newParcel = snapshot.getValue(YourClassConverter::class.java)!!
}
}
            

override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) { }
override fun onChildRemoved(snapshot: DataSnapshot) { }
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {}
override fun onCancelled(error: DatabaseError) {}
}
refDB.addChildEventListener(childEventDataListener!!)
}
}

YourClassConverter 类应该遵循下面所示的 getValue 头注释中指出的这条规则。我更喜欢使用这个转换器,因为我可以控制传递的默认值时,其中一些没有定义在火库。

此方法用于将此快照中包含的数据封送到您选择的类中。该类必须满足两个简单的约束: 课堂上必须有一个不接受任何参数的缺省构造函数 该类必须为要分配的属性定义公共 getter。没有公共 getter 的属性将在反序列化实例时设置为它们的默认值 示例类可能类似于:

 class Message {
private String author;
private String text;


private Message() {}


public Message(String author, String text) {
this.author = author;
this.text = text;
}


public String getAuthor() {
return author;
}


public String getText() {
return text;
}
}




// Later
Message m = snapshot.getValue(Message.class);