android 中的高级 Firebase 适配器

Advanced firebase adapter in android

基本上我的问题是我在 firebase db 中存储了一个具有多个属性的用户列表,其中一些是私人信息所以我想拒绝访问它们。规则不是答案,因为它们不能用作过滤器。

我的解决方案是为 "users" 创建两个新属性:"pvt"(私有)和 "pb"(public)并在其中存储正确的属性.

创建新用户我首先使用:

mDatabase.child("users").child(prefs.getString("id firebase", " ")).child("public").setValue(newUserPublic);
mDatabase.child("users").child(prefs.getString("id firebase", " ")).child("private").setValue(newUserPrivate);

其中 newUserPublic 和 newUserPrivate 是简单自定义 classes 的对象,它们为用户属性提供 getter 和 setter(一个用于 public,另一个用于私人信息)。

我的最终目标是创建一个仅使用每个用户的 public 属性的排行榜,但我无法使用此配置创建合适的 ListAdapter。

我最后的尝试是创建一个名为 User

的新 class
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;
}

}

创建新用户:

User user = new User(newUserPublic, newUserPrivate);
mDatabase.child("users").child(prefs.getString("id firebase", " ")).setValue(user);

当前适配器是

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

但它不起作用(//代码永远不会执行)。

你知道我该如何解决这个问题吗?

这是 Firebase 中的测试用户:

编辑: 尝试在查询中使用 pb/score 但它崩溃了。 我认为问题是 firebase 无法处理复杂的对象或者我遗漏了一些东西。我还有其他代码部分可以检索单个用户数据,所以我使用

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

        }
    });

设置用户时崩溃。我认为如果我使用用户对象将用户保存在我的数据库中,我可以用相同的方式检索它们,但我可能错了。

此代码:

DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference("users");
Query query = mDatabase.child("pb").orderByChild("points");

将指向 /users/pb 并按 users/pb/??/points 排序。如果您寻找指向 /users/?? order by users/??/pb/points 的查询,那么我认为 Firebase 目前无法做到这一点。 Check this post

当您在某个位置调用 orderByChild() 时,Firebase 会将每个节点直接置于该位置下,并将其排序到您指定的子节点上。由于您在 /users 上调用 orderByChild("points"),它会获取 /users 下的节点并将它们排序在它们的(不存在的)points 属性.[=18= 上]

要对每个用户的 pb/points 属性 进行排序,请在对 orderByChild() 的调用中使用该路径。所以:

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

您可以使用 firebase 列表视图适配器,它可以为您完成很多工作。但是您可能想要更改您的用户对象。

Query query = FirebaseDatabase.getInstance().getReference("users").orderByChild("pb/points");

FirebaseListAdapter adapter = new FirebaseListAdapter(activity, User.class, R.id.modelLayout, query) {
        @Override
        protected void populateView(View view, User user, int i) {
            //view is current view
            //user is current user
            //i is position
            TextView points = view.findViewById(R.id.pointsTextView);
            String userPoints = user.getPb().getPoints();

            points.setText(userPoints);
        }
    };

然后在视图上应用适配器

listview.setAdapter(adapter);