我正在尝试从Android的Firebase获取用户列表。
我已经有了用户的uuid,并使用它试图获取整个对象。 uuid既是节点名称,又是用户节点内的字段(当然是相同的)。
这是我的代码:
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("users");
Query query = usersRef.orderByChild("uuid").equalTo(animalMarker.getUserUid());
query.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Log.d(TAG, "onDataChange: xxxxxxxx---- entered onDataChange");
// go to node "users/userUID" , becuase dataSnapshot is parent node
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Log.d(TAG, "xxxxxxxx---- onDataChange: ds= " + ds);
User user = ds.getValue(User.class);
Log.d(TAG, "xxxxxxxx---- onDataChange: user=" + user);
// createdByTV.setText("Created by \n" + user.getEmail());
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
我不知道错误“期望的列表但有HashMap”是来自整个DataSnapshot本身,还是来自用户内部的动物列表(用户类具有字段动物列表)
我已经检查了类似的问题Andorid-Expected a List while deserializing, but got a class java.util.HashMap 还有其他几个,但我仍然不明白哪里出了问题。
编辑:我想获取用户电子邮件,因为它是ID(uuid)。尽管不需要获取整个User对象,但我对如何完成工作感到好奇,因为我无法做到这两个目的。
编辑:这是我的用户类
public class User {
private String uuid;
private String email;
private String name;
private List<User> friends;
private List<Animal> animals;
public User() {
}
public User(String email, String name) {
this.email = email;
this.name = name;
}
public User(String uuid, String email, String name) {
this.uuid = uuid;
this.email = email;
this.name = name;
}
... // getters and setters, toString and other such
}
当尝试获取其中没有动物节点的User时,一切正常。但是当尝试使用户进入动物节点时,应用程序崩溃。
答案 0 :(得分:2)
实际上,我回答了这个问题,但是在这种情况下,问题有所不同。因此,您将收到以下错误:
期望列表但获得了HashMap
因为每个用户对象内存在的animals
节点不是不是,动物对象列表实际上就是动物对象的地图,所以才出现此错误。
虽然没有必要获取整个User对象,但是由于无法做到这两个原因,我对它的实现方式感到好奇。
是的,您只需使用以下代码行即可获取电子邮件地址:
String email = ds.child("email").getValue(String.class);
现在,要将DataSnapshot
对象映射到User
并获取特定用户的动物对象列表,请删除:
//private List<User> friends;
//private List<Animal> animals;
并使用以下代码行:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference animalsRef = rootRef.child("users").child(uid).child("animals");
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<Animal> animalList = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Animal animal = ds.getValue(Animal.class);
animalList.add(animal);
}
//Do what you need to do with the animalList
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
animalsRef.addListenerForSingleValueEvent(valueEventListener);
答案 1 :(得分:0)
动物列表不在用户内部,而是在用户节点内部。无论如何,将其置于用户对象内部似乎比所需的嵌套更多。您应该为动物设置另一个节点
user_animals:{
uid:{key1:{}, key2:{}
}
现在的问题是您要查询而不是获取节点值
usersRef.child(uid).addSingleEvent..
...onDataChange...
User user = datasnapshot.getValue(User.class);
您需要创建一个User类,以在RTD中反映您的用户属性
答案 2 :(得分:0)
构建树的方式是问题的根源。
我今天在重构一个旧项目的 firebase 树时遇到了同样的错误,所以我在谷歌中查找错误并找到了这个页面,我注意到你的动物节点中的这 3 个用户属性看起来不合适。
所以我回到我的树上,显然我错误地在我的一个列表节点中添加了一个键:值对,所以我删除了它们,一切都很好。
问题:
这是因为您有一个动物列表,并且在该列表中您有这 3 个键值(电子邮件、uuid、名称),这会混淆 firebase 序列化,因此他试图将其转换为哈希图
解决办法:
我认为如果您不解决它并执行以下操作,您将来会受益:电子邮件、名称和 uuid 3 个用户属性应包含在用户内部的不同节点中树,类似 user_data 的东西,你应该有一个不同的节点,用于只有动物列表的动物!
那么您的 pojo 应该类似于:一个 User
类,具有 UserData
和 List<Animal>
的属性以及相应的序列化名称。