Basically my problem is that I had stored in firebase db a list of users with multiple attributes, some of them were private information so I wanted to deny access to them. Rules aren't the answer because they can't be used as filters.
My solution was to create two new attributes for "users": "pvt" (private) and "pb" (public) and to store inside of them the correct attributes.
To create new users I used first:
mDatabase.child("users").child(prefs.getString("id firebase", " ")).child("public").setValue(newUserPublic);
mDatabase.child("users").child(prefs.getString("id firebase", " ")).child("private").setValue(newUserPrivate);
where newUserPublic and newUserPrivate are objects of simple custom classes that offers getters and setters for user's attributes (one for public and the other for private information).
My final goal was to create a leaderboard that uses only public attributes of each user but I wasn't able to create a proper ListAdapter with this configuration.
My final try was to create a new class called User
public class User {
public UserDataPrivate getPvt() {
return pvt;
}
public void setPvt(UserDataPrivate pvt) {
this.pvt = pvt;
}
public UserDataPublic getPb() {
return pb;
}
public void setPb(UserDataPublic pb) {
this.pb = pb;
}
private UserDataPrivate pvt;
private UserDataPublic pb;
public void setId(String id) {
this.id = id;
}
private String id;
public User(String id, UserDataPublic pb, UserDataPrivate pvt){
this.pvt=pvt;
this.pb=pb;
this.id=id;
}
}
to create new user with:
User user = new User(newUserPublic, newUserPrivate);
mDatabase.child("users").child(prefs.getString("id firebase", " ")).setValue(user);
and the current adapter is
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference("users");
Query query = mDatabase.child("pb").orderByChild("points");
ListAdapter adapter = new CustomFirebaseAdapter<User>(this, User.class, R.layout.list_item, query) {
@Override
protected void populateView(View v, User model, int position) {
//code that uses model.getPb()
}
};
but it doesn't work (//code is never executed).
Do you have any idea how I can solve this?
This is a test user in Firebase:
EDIT: Tried to user pb/score inside the query but it crashes. I think the problem is that firebase can't handle complex objects or I'm missing something. I have other code portions wHich retrieve single user data so I use
final DatabaseReference userDatabase = mDatabase.child("users").child(prefs.getString("id firebase", " "));
userDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
//...
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
and it crashes when setting user. I thought that if I save users in my db using user objects I could retrieve them in the same way but I'm probably wrong.
When you call orderByChild()
on a location, Firebase takes each node directly under that location and orders it on the child you specify. Since you call orderByChild("points")
on /users
, it takes the nodes under /users
and orders them on their (non-existing) points
property.
To order each user on their pb/points
property, use that path in the call to orderByChild()
. So:
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference("users");
Query query = mDatabase.orderByChild("pb/points");
ListAdapter adapter = new CustomFirebaseAdapter<User>(this, User.class, R.layout.list_item, query) {
@Override
protected void populateView(View v, User model, int position) {
//code that uses model.getPb()
}
};