Как выложить sh (добавить) список в базе данных Firebase Realtime из Unity, C#? - PullRequest
0 голосов
/ 06 марта 2020

Итак, я хочу сохранить инвентарь игрока в базе данных Firebase Realtime. Я настроил базовую c схему и хочу добавить предметы (на самом деле их имена) в «ветку» инвентаря. Я пытаюсь сделать это с помощью метода pu sh, но он сейчас не работает для меня.

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

Что я делаю не так?

public void pickUp() {
        Transform free_place = findFirstFreePlace();
        if(free_place) {
            for (int i = 0; i < items.Length; i++) {
                if (free_place.name.Contains(i.ToString())) {
                    items[i] = currentPickable;
                    reference.Child("users").Child(auth.CurrentUser.UserId).Child("inventory").Child(items[i].item_name).Push();
                    lastIndex = i;
                }
            }
            free_place.GetChild(0).GetChild(0).GetComponent<Image>().sprite = items[lastIndex].item_pic;
            free_place.GetChild(0).GetChild(0).GetComponent<Image>().enabled = true;
            free_place.GetChild(1).GetComponent<Image>().enabled = true;
            free_place.GetChild(1).GetComponent<Button>().interactable = true;
        }
    }

Ответы [ 2 ]

0 голосов
/ 07 марта 2020

Хорошо, так что я наконец понял это. С помощью генерации уникального идентификатора метода Push() я могу добавить дочерние элементы с тем же именем элемента в узел инвентаря. Сначала я создаю этот уникальный идентификатор, затем добавляю этот уникальный идентификатор в базу данных и устанавливаю его значение в качестве имени элемента.

Редактировать: я смешал свое исходное решение с решением Pux0r3, чтобы оно использовало async / жду.

public async void pickUp() {
    Transform free_place = findFirstFreePlace();
    if (free_place) {
        int lastIndex = 0;
        var elements = new List<string>();
        for (int i = 0; i < items.Length; i++) {
            if (free_place.name.Contains(i.ToString())) {
                items[i] = currentPickable;
                elements.Add(items[i].item_name);
                lastIndex = i;
            }
        }
        string key = reference.Child(auth.CurrentUser.UserId).Child("inventory").Push().Key;
        await reference.Child("users").Child(auth.CurrentUser.UserId).Child("inventory").Child(key).SetValueAsync(currentPickable.item_name);
        free_place.GetChild(0).GetChild(0).GetComponent<Image>().sprite = items[lastIndex].item_pic;
        free_place.GetChild(0).GetChild(0).GetComponent<Image>().enabled = true;
        free_place.GetChild(1).GetComponent<Image>().enabled = true;
        free_place.GetChild(1).GetComponent<Button>().interactable = true;
    }
}
0 голосов
/ 06 марта 2020

Я предполагаю, что есть небольшая путаница в отношении того, что Push() делает в этом контексте. Если вы прочитали документацию , там написано:

Добавить в список данных. Каждый раз, когда вы звоните Pu sh (), Firebase генерирует уникальный ключ, который также может использоваться в качестве уникального идентификатора, например user-scores/<user-id>/<unique-score-id>.

По сути, это дает вам место, где вы можете безопасно писать, а не добавлять что-то в базу данных. Вы должны проверить образец , но я думаю, что я могу проиллюстрировать как то, что вы собираетесь делать, так и классный способ использования Push() для вашего случая использования.

public async void pickUp() {
    Transform free_place = findFirstFreePlace();
    if(free_place) {
        int lastIndex = 0;
        var elements = new List<string>();
        for (int i = 0; i < items.Length; i++) {
            if (free_place.name.Contains(i.ToString())) {
                items[i] = currentPickable;
                elements.Add(items[i].item_name);
                lastIndex = i;
            }
        }
        await reference.Child("users").Child(auth.CurrentUser.UserId).Child("inventory").SetValueAsync(itemNames);
        free_place.GetChild(0).GetChild(0).GetComponent<Image>().sprite = items[lastIndex].item_pic;
        free_place.GetChild(0).GetChild(0).GetComponent<Image>().enabled = true;
        free_place.GetChild(1).GetComponent<Image>().enabled = true;
        free_place.GetChild(1).GetComponent<Button>().interactable = true;
    }
}

Что я Я делаю здесь, что я строю список предметов перед рукой. Затем я установил запись инвентаря в этот список. Если бы я зависел от предыдущего состояния, я бы предпочел сделать это вместо транзакции.

Я также использую async / await. Я не уверен, насколько важно, чтобы этот logi c запускался до того, как вы обновите пользовательский интерфейс вашей игры, но установка чего-либо в Firebase является асинхронной операцией (работает в фоновом режиме). Вы можете пропустить это, если не важно, чтобы вы оставались в курсе c.

Если вы хотели иметь уникально идентифицированные ячейки для оружия. Вместо этого вы можете сделать что-то вроде:

var childReference = reference.Child("users").Child(auth.CurrentUser.UserId).Child("inventory");
var key = childReference.Key;

// ... more logic here ...

childReference.Child(key).SetValueAsync(item_name);

Еще несколько советов:

  • Я бы порекомендовал вам использовать слушатель ValueChanged , когда это возможно, чтобы сохранить состояние вашей игры совпадает с состоянием вашего сервера. База данных реального времени всегда будет работать асинхронно в фоновом режиме, и таким образом вы можете помочь оставаться в курсе, когда станет доступно больше данных.
  • Если асинхронное программирование в Unity является для вас новым, ознакомьтесь с моим постом по теме .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...