仅从联系人列表的Firebase检索数据

时间:2018-08-02 17:58:39

标签: java android firebase firebase-realtime-database

我正在开发一个Android应用,我想检索用户的帖子,其联系电话以timestamp的降序存储在手机中。

目前,我正在检索所有用户列表。如果手机中存在联系电话,并显示该用户的帖子。由于我想按时间戳的降序进行排序,因此我必须先检索所有联系人的帖子,然后再对其进行排序。

Users: { 
            7828272892 : {
                 name: xyz, 
                 gender: male,
                 phoneNo: 7828272892
                 PostsForThisUser: {
                     SomeKey1: {
                         content: "This is post 1", timestamp: "123"} 
                     SomeKey2: {
                         content: "This is post 2", timestamp: "124"}   

                }},

            7924272894 : {
                name: abc,
                gender: male,
                phoneNo: 7924272894
                PostsForThisUser: {
                         SomeKey3: {
                             content: "This is post 1", timestamp: "234"} }},
            }

我能想到的一个更好的解决方案是,为帖子创建单独的表格并跟踪帖子的关键。但是,在这里我也必须首先获取所有帖子,并按时间戳对其进行排序。有更好的解决方案吗?

哪个更好?

  1. 要检索所有用户,然后签入联系人列表。
  2. 打开手机中每个联系人的监听器。

1 个答案:

答案 0 :(得分:1)

首先,即使您的模式可以帮助您实现所需的目标,我也可以说这不是一个非常可行的模式,因为您要在每个用户对象下添加其所有帖子。这意味着每次您尝试获取特定用户的详细信息(例如name)时,您都在下载整个用户对象,包括他的所有帖子,我可以说这是在浪费资源。 。试想一下,如果需要显示数据库中所有用户名的列表,会发生什么情况。因此,在用户名旁边,您将下载所有用户的所有帖子。这是一个坏习惯。

请记住,构建Firebase数据库没有完美的解决方案。最好的解决方案是适合您的需求并使您的工作更轻松的解决方案。考虑到所有内容均适用于视图,我认为您可以有一个架构,在该架构中,应创建一个名为posts的新顶级集合,并在每个用户电话号码下添加其个人帖子。模式应如下所示:

 Firebase-root
    |
    --- users
    |    |
    |    --- userPhoneNo
    |          |
    |          --- name: "xyz,"
    |          |
    |          --- gender: "male"
    |          |
    |          --- phoneNo: "7828272892"
    |
    --- posts
         |
         userPhoneNo
            |
            --- postIdOne
            |     |
            |     --- content: "This is post 1"
            |     |
            |     --- timestamp: 123
            |
            --- postIdTwo
                  |
                  --- content: "This is post 2"
                  |
                  --- timestamp: 124

因此,为了获得特定用户的所有帖子,无需下载其他任何内容。要使用模型类订购特定用户的所有帖子,请使用以下代码:

String phoneNo = FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("posts").child(phoneNo).orderByChild("timestamp");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            PostClass postClass = ds.getValue(PostClass.class);
            Log.d("TAG", postClass.getContent());
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {}
};
query.addListenerForSingleValueEvent(valueEventListener);

使用String类,或者根据需要甚至更简单:

String phoneNo = FirebaseAuth.getInstance().getCurrentUser().getPhoneNumber();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("posts").child(phoneNo).orderByChild("timestamp");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String content = ds.child("content").getValue(String.class);
            Log.d("TAG", content);
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {}
};
query.addListenerForSingleValueEvent(valueEventListener);

在两种情况下,您的logcat的输出将是:

This is post 1
This is post 2

或者如果您使用的是相反顺序:

This is post 2
This is post 1

编辑:根据聊天室中的评论,OP要求解决听起来像这样的问题:

“让我重申一下我的问题。在我的系统中,我假设有10,000个用户。但是,一个用户只能看到其联系电话的用户的帖子。就像WhatsApp故事功能一样。”

响应:在这种情况下,您应该在每个用户下创建一个map,您需要在其中存储该用户拥有的用户联系电话。但是在这种情况下,您应该查询数据库两次。首先,获取其拥有的用户的联系电话;其次,根据这些电话以实际获取这些用户的帖子。