Android Firebase根据群组成员资格创建列表

ImA*_*lay 8 android firebase firebase-realtime-database

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

对Firebase来说相对较新,所以仍然试图将我的数据结构展平.

JSON(显示"水果"和"组")如下所示:

 {
  "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"
    }
  }    ...
        ...
}
Run Code Online (Sandbox Code Playgroud)

在应用程序本身中,用户可以创建一个列表,将整个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());
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

问:如何使用组实现此过程?例如,用户创建列表并且仅希望新创建的列表包含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
}
Run Code Online (Sandbox Code Playgroud)

最后,这里就是我相信的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"
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

这是解决这个问题的正确方法吗?任何帮助或正确方向上的一点都会很棒.

ImA*_*lay 0

尽管自我最初发布此问题以来我的用法略有变化,但经过一些细微调整后,下面的两个用例仍然适用。可能有更好的方法来解决这个问题,所以我绝对欢迎其他人的任何建议或想法。

总而言之,您以具有groups路径和users路径的方式构建数据库。该users路径包含对组的引用。获取特定组的子项的数据快照(只需要键)并将它们添加到 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

}
Run Code Online (Sandbox Code Playgroud)

根据组成员身份显示人员列表(例如使用 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());
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

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

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

     }, 
     "fakeUserB":{

     }
   }
}
Run Code Online (Sandbox Code Playgroud)