Как загрузить / получить отношение «многие ко многим» в базе данных Firebase Realtime - PullRequest
0 голосов
/ 15 сентября 2018

В моем проекте Android мне нужно, чтобы Firebase загружал / извлекал мой список 'children' (user with name) при извлечении объекта (группы), который находится в отношении "многие ко многим", как в приведенной ниже структуре:

App {
   "users" : {
        "user123jsbgkjwroi" : {
            "name" : "Mr Guy", 
            "groups" : {
                "group567-alkfhhiuall_dajk" : true,
                ...
            }
        }
    }
    "groups" : {
        "group567-alkfhhiuall_dajk" : {
            "name" : "My Group 1",
            "groupShortCode" : "567",
            "groupPassPhrase" : "ABC",
            "members" : {
                 "user123jsbgkjwroi" : {
                     "A": 2,
                     "B": 1,
                     "C": 33
                 },
                 ...    
            }
        }
    }
} 

Я, вероятно, сделал мою жизнь сложнее, чем нужно, потому что я новичок в NoSQL, мой объект группы использует пользователя в качестве ключа карты, по сравнению с другим объектом, который содержит список (A, B, C),Примерно так:

class Group {
    private String name;
    private Map<User, GroupItems> members;
}

Когда новый пользователь присоединяется к группе, введя groupShortCode и groupPassPhrase, мне нужно загрузить весь объект Group вместе с другими пользователями (членами) группы.

Но я не хочу делать это рекурсивно (я бы предпочел получить как можно меньше документов - я не должен загружать другие группы пользователя).Вот что я попробовал:

dbReference.child("groups").orderByChild("groupShortCode").equalTo(...)
           .addListenerForSingleValueEvent(new ValueEventListener() {

    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        List<User> users = new ArrayList<>();

        //TODO: Here I need load each User, but it means tons of calls   
        Iterable<DataSnapshot> profileKeys = dataSnapshot.child("members").getChildren();
        for (DataSnapshot keySnapshot : profileKeys) {
            dbReference.child("users").child(keySnapshot.getKey())
              .addListenerForSingleValueEvent( ... );
        }         

        //this constructor is because of the Object-to-Object Map so dataSnapshot.getValue() fails
        Group group = new Group(dataSnapshot, users);
        ...
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        ...
    }

});

Как мне сделать это правильно, эффективно!?

1 Ответ

0 голосов
/ 17 сентября 2018

Для этого сценария чаще всего используются четыре списка верхнего уровня: группы, пользователи, groupUsers и userGroups.Это позволяет вам загружать именно то, что вам нужно, за дополнительную плату.См. Соотношение «многие ко многим» в Firebase .

. Если вас беспокоят проблемы, может быть полезно знать, что все запросы передаются по одному соединению, так что весьма маловероятно, что он преуспеет идругие терпят неудачу.Вероятность сбоя одного из-за проблем с соединением не больше при нескольких вызовах, чем при одиночном вызове.Смотри http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786

...