0

所以,我想将播放器的库存存储在 Firebase 实时数据库中。我设置了一个基本模式,我想在库存“分支”下添加项目(实际上是它们的名称)。我正在尝试使用 push 方法来做到这一点,但它现在对我不起作用。

我得到了以下脚本,它更新了玩家的库存客户端,并且应该更新数据库,并附加库存“分支”。

我究竟做错了什么?

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;
        }
    }
4

2 回答 2

0

我猜想Push()在这种情况下做什么会有轻微的混淆。如果您阅读文档,它会说:

添加到数据列表。每次调用 Push() 时,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;
    }
}

我在这里所做的是我事先建立了一个项目列表。然后我将库存条目设置为此列表。如果我依赖以前的状态,我可能更愿意将其作为事务来执行。

我也使用异步/等待。我不确定在更新游戏 UI 之前运行此逻辑有多重要,但在 Firebase 中设置任何内容都是异步操作(它在后台运行)。如果您保持同步并不重要,您可以省略它。

如果您想拥有唯一标识的武器插槽。您可以改为执行以下操作:

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

// ... more logic here ...

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

还有一些提示:

于 2020-03-06T20:11:19.230 回答
0

好的,所以我终于想通了。借助Push()方法的唯一 id 生成,我可以将具有相同项目名称的子项添加到库存节点。首先,我创建该唯一 ID,然后将该唯一 ID 添加到数据库中,并将其值设置为项目名称。

编辑:我将我的原始解决方案与 Pux0r3 的解决方案混合在一起,以便它使用 async/await。

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;
    }
}
于 2020-03-07T11:52:28.870 回答