Поиск по подмассивам в Firebase - PullRequest
0 голосов
/ 30 марта 2020

Мой заголовок не очень точный, но я не могу назвать проблему, с которой сталкиваюсь.

Итак, я учусь использовать firebase и angularfire, и я учусь манипулировать data.

Все было найдено, пока я не встретил этот тип массива.

enter image description here

Это моя база данных реального времени от Firebase, и это история.

Основной массив - это собственная история, он состоит из двух массивов (0 и 1), которые относятся к истории пользователя 0 и пользователя 1.

В массив пользователя 0, его идентификатор пользователя (_ID) и два вложенных массива (0 и 1), которые относятся к уровням, которые он сделал.

В каждом вложенном массиве указано, сколько раз уровень было сделано, идентификатор (_id) уровня и несколько вложенных массивов, содержащих данные о каждом запуске уровня.

Вроде сложно! Я надеюсь, что вы понимаете мою базу данных. Я согласен с тем, что у меня нет наилучшей практики структурирования моей базы данных.

Моя проблема в том, что я пытаюсь найти этот тип массивов для моего angularjs приложения.

Например, я пытаюсь сделать эти переменные:

$scope.history
$scope.userHistory
$scope.currentLevelUserHistory
$scope.lastRunCurrentLevelUserHistory

Мне удалось получить два первых переменные, но я не понимаю, почему я не работаю, как nexts .

Получение истории очень просто, я просто использую эту функцию на своей фабрике

getHistoriques : function () {
    return historiques;
}

Где "историческая справка" относится к этому

var ref = firebase.database().ref().child("historiques");
var historiques = $firebaseArray(ref);

Получение userHistory было немного сложнее.

Я создал эту функцию

function search(key, array){
    console.log("Searching array with the key : " + key);
    for (var i=0; i < array.length; i++) {
        if (array[i]._id === key) {

            console.log(array[i]);
            return array[i];

        }
        else {

        }
    }
}

И на выходе получается такой объект.

enter image description here

Но чтобы перейти к следующему шагу: currentLevelUserHistory. Это было невозможно для меня. Я попробовал 10 разных способов, но я не смог заставить его работать.

Моя последняя попытка заключалась в том, чтобы заново ввести вывод предыдущего объекта с идентификатором уровня в функцию поиска.

Но я получаю "undefined".

Я пробовал так много вещей, как добавление [0] к моему объекту, добавление множества вещей. Но я не могу понять, почему это не работает. Для меня массив и вложенный массив всегда одинаковы.

Почему это не работает? Это из-за того, что вывод функции модифицирует мой массив?

Я знаю, мой вопрос очень длинный. Огромное спасибо всем, у кого хватило смелости прочитать это.

Большое спасибо.

Первое редактирование:

users
    |
    - userId (according to firebase auth)
        |
        - name : ...
        |
        - surname : ...
        |
        - age : ...
        |
        - allowed levels :
                        |
                        - allowedLevel001 : levelId
                        |
                        - allowedLevel002 : levelId
                        |
                        - allowedLevel003 : levelId
        -...

levelsData
    |
    - levelId
        |
        - level name : ...
        |
        - level description : ...
        |
        - first step
            |
            - step name : ...
            |
            - step desc : ...
            |
            - action needed : ...
            |
            - time : ...
        - second step
            |
            - step name : ...
            |
            - step desc : ...
            |
            - action needed : ...
            |
            - time : ...    
    |
        -...    

levelsRunData
    |
    - userId+levelId
        |
        - run001
            |
            -
            first step result :
                |
                - ...
            second step result :
                |
                - ...   
            |
            -...
        - run002
            |
            -
            first step result :
                |
                - ...
            second step result :
                |
                - ...   
            |
            -...    

1 Ответ

1 голос
/ 02 апреля 2020

Я хотел бы сделать несколько предложений относительно структуры вашей базы данных. Они основаны на том, что я считаю вашим вариантом использования. Я могу быть совершенно неправ, конечно. Сначала пара замечаний:

  1. Вам нужно рассматривать базу данных Firebase RTDB как карту пар ключ / значение, а не массив. Он позволяет вам разместить массив в БД, но он создаст из него серию пар ключ / значение с ключами, начинающимися с 0 и увеличивающимися на 1 (вы вроде как делаете это в своей текущей структуре, но я думаю, что это может привести к другим проблемам).
  2. Вам нужно подумать, как должна выглядеть база данных, когда вам нужно обрабатывать 100 тыс. пользователей. Тогда объемы хранения и загрузки данных станут очень важными, или ваше приложение остановится, и Google представит вам счет на 1000 долларов.

ИМХО, ваших пользователей нужно идентифицировать приличным уникальный ключ, а не 0, 1, 2. Это откусит вас в долгосрочной перспективе, поверьте мне. Во многих структурах БД используется ИД пользователя, который создается, когда пользователь проходит аутентификацию в приложении с помощью аутентификации Firebase - вы должны использовать его для всех ссылок на ваших пользователей в базе данных. Это избавляет от свойства id:, которое вы сохраняете для каждого пользователя, потому что оно уже находится в ключе.

Я не могу видеть, какие данные у вас есть в под-массивах 0 и 1, но вы уже вниз на 5 уровней и, хотя это выполнимо, не очень хорошо go глубокое вложение в No SQL db.

Так что, опять же ИМХО, ваша база данных может выглядеть следующим образом (я предполагаю, historyiques - root, и вам не нужно хранить какие-либо другие данные о пользователе, например, имя, возраст и т. д. c. Если вы это сделаете, вам нужен узел с именем users с идентификатором пользователя в качестве ключа.):

Два узла базы данных с именами levelCompleted и levelRunData. Они выглядели бы как ...

levelsCompleted
    |
    - userId
        |
        - levelId001 : levelRunCount
        (number of zeroes in levelId depends on how many possible levels there are)
        |
        - levelId002 : levelRunCount
        |
        -...

levelsRunData
    |
    - userId+levelIdnnn (concatenate the two ids)
        |
        - run001
            |
            - run data (don't know what is in here).
        (number of zeroes in run depends on how many possible runs there are)
        |
        - run002
            |
            - run data
        |
        - run003
            |
            - run data
        |
        -...

Тогда становится довольно просто читать нужные данные на основе идентификатора пользователя и идентификатора уровня. Надеюсь, что это имеет смысл.

Обновление на основе вашего первого редактирования:

Пожалуйста, ознакомьтесь с предложенной структурой ниже. Я сейчас использую фактические (предлагаемые) имена свойств. Также, для ясности, вот предлагаемые ключи записи для каждого узла:

Node            Key Format                                   Name in Structure
----            ---------------------                        -----------------
users           <28 character user id from firebase_auth>    userId
levelsData      <'level'nnn eg. level001, level002>          levelId
levelsRunData   <userId + levelId + 'run'nnn>                N/a

Затем мы можем обсудить это в чате.

Структура базы данных:

users
    |
    - userId (according to firebase auth)
        |
        - name : ...
        |
        - surname : ...
        |
        - age : ...
        |
        - allwdLvls
            |
            - level001 : levelRunCount
            |
            - level002 : levelRunCount
            |
            - level003 : levelRunCount
        -...

levelsData
    |
    - level001
        |
        - levelName : ...
        |
        - levelDesc : ...
        |
        - step001
            |
            - stepName : ...
            |
            - stepDesc : ...
            |
            - actionNeeded : ...
            |
            - time : ...
        - step002
            |
            - stepName : ...
            |
            - stepDesc : ...
            |
            - actionNeeded : ...
            |
            - time : ...    
    |
    - level002
        |
        - levelName : ...
        -... 
    -...

levelsRunData
    |
    - <userId>+<levelId>+run001
        |
        - step001
            |
            - ...
            |
            - ...
        |
        - step002
            |
            - ...
            |
            - ...
        |
        -...
    - <userId>+<levelId>+run002
        |
        - step001
            |
            - ...
            |
            - ...
        |
        - step002
            |
            - ...
            |
            - ...
        |
        -...
    |
    -...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...