【问题标题】:Android Firebase create lists based on group membershipAndroid Firebase 根据组成员身份创建列表
【发布时间】:2016-09-15 02:00:55
【问题描述】:

我正在尝试创建一个仅包含特定组项目的列表。例如,我自己在数据库控制台中创建/编写了一个“fruits”节点和一个“groups”节点(包括组的键)。

对于 Firebase 来说相对较新,因此我仍在尝试围绕扁平化数据结构展开工作。

JSON(显示“fruits”和“groups”)如下所示:

 {
  "fruits" : {
    "apple" : {
      "color" : "appleColorValueHere",
      "groups" : {
        "GroupABCKey" : true,
        "GroupXYZKey" : true
      },
      "origin" : "appleOriginValueHere",
      "size" : "appleSizeValueHere"
    },
    "orange" : {
      "color" : "orangeColorValueHere",
      "groups" : {
        "GroupABCKey" : true,
        "GroupXYZ" : true
      },
      "origin" : "orangeOriginValueHere",
      "size" : "orangeSizeValueHere"
    },
    "strawberry" : {
      "color" : "strawberryColorValueHere",
      "groups" : {
        "GroupJKLKey" : true
      },
      "origin" : "strawberryOriginValueHere",
      "size" : "strawberrySizeValueHere"
    }
  },
  "groups" : {
    "GroupABCKey" : {
      "members" : {
        "apple" : true,
        "orange" : true
      },
      "name" : "Group ABC Name Here"
    },
    "GroupJKLKey" : {
      "members" : {
        "strawberry" : true
      },
      "name" : "Group JKL Name Here"
    },
    "GroupXYZKey" : {
      "members" : {
        "apple" : true,
        "orange" : true
      },
      "name" : "Group XYZ Name Here"
    }
  }    ...
        ...
}

在应用程序本身中,用户可以创建一个列表,将整个 fruits 节点复制到他们新创建的列表中(请参阅下面的 JSON 以了解 user-list-items)。然后我使用FirebaseRecyclerAdapter显示这些项目

这是我如何做到这一点的代码:

private void writeNewFruitList(String userId, String username, String email, String title) {
    final String key = databaseReference.child("fruit-lists").push().getKey();
    UserLists userLists = new UserLists(userId, username, email, title);

    HashMap<String, Object> updatedListToAddMap = new HashMap<>();
    HashMap<String, Object> itemToAdd =
            (HashMap<String, Object>) new ObjectMapper().convertValue(userLists, Map.class);
    updatedListToAddMap.put("/fruit-lists/" + key, itemToAdd);
    updatedListToAddMap.put("/user-fruit-lists/" + userId + "/" + key, itemToAdd);

    databaseReference.updateChildren(updatedListToAddMap);

    final DatabaseReference subDatabaseReference = FirebaseDatabase.getInstance().getReference();
    subDatabaseReference.child("fruits").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot child : dataSnapshot.getChildren()) {
                Log.d(TAG, child.getKey());
                Log.d("fruitValues::", dataSnapshot.getValue().toString());
                final String fruitKey= child.getKey();
                FruitModel fruitModel = child.getValue(FruitModel.class);

                Map<String, Object> nodeValues = fruitModel.toMap();
                Map<String, Object> childUpdates = new HashMap<>();

                String new_path = "/user-list-items/" + key + "/" + fruitKey+ "/";
                childUpdates.put(new_path, nodeValues);
                subDatabaseReference.updateChildren(childUpdates);

            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e(TAG, "onCancelled", databaseError.toException());
        }
    });
}

问:如何使用组来实施此流程?例如,用户创建了一个列表,并且只希望新创建的列表包含GroupABCKey 的水果,但他们还想要这些水果的详细信息(大小、原产地等)。

Q2:编辑我的FruitModel.java 以说明群组的最佳方式是什么?

public class FruitModel {
    public String size;
    public String origin;
    public String color;

    public FruitModel() {
    }

    public FruitModel(String size, String origin, String color) {
        this.size = size;
        this.origin = origin;
        this.color = color;
    }

    @Exclude
    public Map<String, Object> toMap() {
        HashMap<String, Object> result = new HashMap<>();

        result.put("size", size);
        result.put("origin", origin);
        result.put("color", color);

        return result;
    }
    // getters & setters
}

最后,我认为user-list-items 节点如果操作正确会是什么样子?

listKey1forUserA 是我正确创建的(除了前面提到的映射组)。

listKey2forUserA 是我要完成的任务 - 用户希望仅使用“GroupJKLKey”中的项目创建和填充列表

  "user-list-items" : {
    "listKey1forUserA" : {
      "apple" : {
        "color" : "appleColorValueHere",
        "groups" : {
          "GroupABCKey" : true,
          "GroupXYZ" : true
        },
        "origin" : "appleOriginValueHere",
        "size" : "appleSizeValueHere"
      },
      "orange" : {
        "color" : "orangeColorValueHere",
        "groups" : {
          "GroupABCKey" : true,
          "GroupXYZKey" : true
        },
        "origin" : "orangeOriginValueHere",
        "size" : "orangeSizeValueHere"
      },
      "strawberry" : {
        "color" : "strawberryColorValueHere",
        "groups" : {
          "GroupJKLKey" : true
        },
        "origin" : "strawberryOriginValueHere",
        "size" : "strawberrySizeValueHere"
      }
    },
    "listKey2forUserA" : {
      "strawberry" : {
        "color" : "strawberryColorValueHere",
        "groups" : {
          "GroupJKLKey" : true
        },
        "origin" : "strawberryOriginValueHere",
        "size" : "strawberrySizeValueHere"
      }
    }
  }

这是解决此问题的正确方法吗?任何帮助或正确方向的观点都会很棒。

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    虽然自从我最初发布这个问题以来我的用法略有变化,但以下两个用例仍然适用,只需稍作调整。可能有更好的方法来解决这个问题,所以我绝对欢迎其他人的任何建议或想法。

    tl;dr 是您以这样一种方式构建数据库,即您有一个 groups 路径和一个 users 路径。 users 路径包含对组的no 引用。获取特定组的孩子的数据快照(只需要键)并将它们添加到 ArrayList。 > 对于 ArrayList 中的每个项目,将其插入 users 路径。

    这将允许访问这些用户的详细信息(或水果,如我最初的问题中所使用的),并能够显示该信息或创建您认为合适的新信息。

    根据群组成员资格创建/编写人员列表

    private void writeListFromGroupMembership(){
    
        final DatabaseReference mainPathReference = FirebaseDatabase.getInstance().getReference();
    
        final ArrayList<String> groupMembers = new ArrayList<>();
    
        DatabaseReference groupsReference = FirebaseDatabase.getInstance().getReference()
                .child("groups")
                .child("someOtherChildYouMayHave")
                .child("nameOfGroupYouAreInterestedIn");
    
        /* Step 1: Get a list of people in a specific group that you are interested in */
        groupsReference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot child : dataSnapshot.getChildren()) {
                    String groupMemberKey = child.getKey();
    
                    if (child.getValue(Boolean.class) != null) {
                        groupMembers.add(groupMemberKey);
                    } else {
                        // TODO
                    }
                }
    
                /* Step 2: Loop through your list of people and insert them as a child like the following: */
                for (int i = 0; i < groupMembers.size(); i++) {
                    final String singleGroupMember = groupMembers.get(i);
    
                    mainPathReference.child("all-groups").child("anotherChildYouMayHave").child(singleGroupMember)
                            .addListenerForSingleValueEvent(new ValueEventListener() {
                                @Override
                                public void onDataChange(DataSnapshot dataSnapshot) {
                                    // Make a POJO for the item and immediately turn it into a HashMap
                                    Person person= dataSnapshot.getValue(Person.class);
                                    Map<String, Object> nodeValues = person.toMap();
    
                                    // Make a map for the items you are adding
                                    Map<String, Object> childUpdates = new HashMap<>();
    
                                    // The path where the items will be copied/written to.
                                    String newPath = "/master-list-items/" + listKey + "/" + singleGroupMember + "/";
    
                                    // Add the items to the update map
                                    childUpdates.put(newPath, nodeValues);
    
                                    // Do the update
                                    mainPathReference.updateChildren(childUpdates);
                                }
    
                                @Override
                                public void onCancelled(DatabaseError databaseError) {
                                    Log.w(TAG, "onCancelled: ", databaseError.toException());
                                }
                            });
                }
            }
    
        // your other onCancelled override method here
    
    }
    

    显示基于组成员身份的人员列表(例如,使用 Spinner):

    public List<Person> persons;
    ...
    private void getGroupMembers(String groupSelected) {
        groupRef= FirebaseDatabase.getInstance().getReference()
                .child("someOtherChildThatYouHouseGroupsUnder")
                .child(groupSelected)
                .child("members");
    
        groupRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot child : dataSnapshot.getChildren()) {
                    String groupMember= child.getKey();
    
                    selectedGroupMembers.add(groupMember);
                }
    
                for (int i = 0; i < selectedGroupMembers.size(); i++) {
                    String singleMember = selectedGroupMembers.get(i);
    
                    singleMemberDatabaseReference = FirebaseDatabase.getInstance().getReference()
                            .child("all-people")
                            .child(singleMember);
    
                    singleMemberDatabaseReference .addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            Person person = dataSnapshot.getValue(Person.class);
                            persons.add(person);
    
                            personAdapter = new PersonAdapter(getApplicationContext(), persons);
    
                            recyclerView.setAdapter(personAdapter);
                        }
    
                        @Override
                        public void onCancelled(DatabaseError databaseError) {
                            Log.w(TAG,"onCancelled: ", databaseError.toException());
                        }
                    });
                }
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.w(TAG, "onCancelled: ", databaseError.toException());
            }
        });
    }
    

    为了显示基于组成员的人员列表,我的数据库结构类似于:

    {
       "all-groups":{
          "groupNameorKeyOfGroupName":{
             "details":{
                "meetingLocation":"110 William Street",
                "someOtherChild":"Your value"
             },
             "members":{
                "fakeUserA":true,
                "fakeUserB":true,
                "fakeUserC":true,
                "fakeUserD":true
             }
          }
       }
       "all-users":{
         "fakeUserA":{
    
         }, 
         "fakeUserB":{
    
         }
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      • 2019-07-05
      • 1970-01-01
      • 2019-03-04
      • 1970-01-01
      相关资源
      最近更新 更多