如何使用Firebase数据库更新适配器中的列表?

时间:2016-11-01 14:38:29

标签: android firebase firebase-realtime-database

我使用的是Android应用,用户在Firebase中拥有friendlist这些结构:

    { users: {
        user_1: {
          name: John
        },
        user_2: {
          name: Jack
        },
       user_3: { 
          name: Georges
       },
   }, 
   { friendships : {
      user_1 : {
        user_2: true,
        user_3: true,
      user_3: {
        user_1: true,
        user_2: true
        }
    }

我想用Recycler View显示朋友列表。我这样做,它的工作原理。

在我的片段中:

public void getUsers() {
    userDataset = new ArrayList<>();
    Query usersQuery = getQuery(mDatabase);

    usersQuery.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot friendshipSnapshot : dataSnapshot.getChildren()) {
                final String userKey = friendshipSnapshot.getKey();

                final DatabaseReference userRef = mDatabase.child("users").child(userKey);

                userDataset.add(userRef);
            }

            FriendsAdapter mAdapter = new FriendsAdapter(getContext(), userDataset);
            mRecycler.setAdapter(mAdapter);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.w(LOG_TAG, "loadFriendship:onCancelled", databaseError.toException());
        }
    });
}

我的适配器:

public class FriendsAdapter extends RecyclerView.Adapter<UserViewHolder>  {

    private Context mContext;
    private List<DatabaseReference> userDataset = new ArrayList<>();

    public FriendsAdapter(Context context, List<DatabaseReference> userDataset) {
        this.mContext = context;
        this.userDataset = userDataset;
    }

    @Override
    public UserViewHolder onCreateViewHolder(ViewGroup parent,
                                             int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_user, parent, false);
        // set the view's size, margins, paddings and layout parameters

        UserViewHolder userViewHolder = new UserViewHolder(mContext, v);
        return userViewHolder;
    }

    @Override
    public void onBindViewHolder(UserViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element

        holder.bindToUser(userDataset.get(position));

    }

    @Override
    public int getItemCount() {
        return userDataset.size();
    }

}

我的ViewHolder

public class UserViewHolder extends RecyclerView.ViewHolder {

private Context mContext;

public TextView firstNameView;
public TextView lastNameView;
public CircleImageView userPhotoView;
public TextView userDistanceView;

public UserViewHolder(Context context, View itemView) {
    super(itemView);

    mContext = context;

    firstNameView = (TextView) itemView.findViewById(R.id.user_first_name);
    lastNameView = (TextView) itemView.findViewById(R.id.user_last_name);
    userPhotoView = (CircleImageView) itemView.findViewById(R.id.user_photo);
    userDistanceView = (TextView) itemView.findViewById(R.id.user_distance);
}

public void bindToUser(DatabaseReference userRef) {

    userRef.addValueEventListener(new ValueEventListener() {
        public void onDataChange(DataSnapshot dataSnapshot) {
            User user = dataSnapshot.getValue(User.class);
            firstNameView.setText(user.firstName);
            lastNameView.setText(user.lastName);

            userDistanceView.setText(user.getDistance(((MainActivity) mContext).currentUserLocation()));

            Picasso.with(mContext).load(user.profilePicture).placeholder(R.drawable.ic_action_account_circle_40).into(userPhotoView);
        }

        public void onCancelled(DatabaseError databaseError) {
            System.out.println("The read failed: " + databaseError.getMessage());
        }
    });

}}

但是现在,我想在列表中对用户进行排序,我不知道如何做到这一点因为我的数据集包含DatabaseReference个对象而不是User个对象。我想我构建数据集的方式很糟糕。您能告诉我如何根据名称对用户进行排序吗?

正如你首先看到的,我获取了我的用户的友谊(在片段中)。通过这种友谊,我创建了与每个​​用户(朋友)相关的DatabaseReference个对象的数据集。最后,在我的ViewHolder中,我获取每个用户的数据并填充视图。因此,我从不在我的数据集中添加用户信息,而只是DatabaseReference

谢谢。

2 个答案:

答案 0 :(得分:0)

您可以像这样从数据库中检索数据。

  // My top posts by number of stars
  String myUserId = getUid();
  Query myTopPostsQuery = databaseReference.child("user-posts").child(myUserId)
    .orderByChild("starCount");
 myTopPostsQuery.addChildEventListener(new ChildEventListener() {
// TODO: implement the ChildEventListener methods as documented above
// ...
});

请仔细阅读此链接,您可以找到有关数据分类的更多信息

https://firebase.google.com/docs/database/android/lists-of-data

答案 1 :(得分:0)

您无法将DatabaseReference转换为User对象。您可以做的是使用getValue将DataSnapshot转换为User对象。

您应该做的是更改存储数据的方式以添加冗余。在NoSQL数据库中,无法像您尝试那样存储非规范化数据。

您的数据可能如下所示:

users: {
  user_1: {
    name: John,
    friends: {
      user_2: {
        name: Jack
      },
      user_3: {
        name: Georges
      },
    }
  },
  user_2: {
    name: Jack,
    frinds: {...}
  },
  user_3: {
    name: Georges,
    friends: {...}
  },
}

然后,您可以更改Query以获取用户好友列表。

这不是您组织数据的唯一方式,这只是一个例子。这取决于你想如何查询数据。