You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中Firebase实时数据库按名称或ID查询异常问题

Unity Firebase实时数据库按ID/产品名称查询问题解决

问题根源分析

  • 数据结构不合理:你当前用数组存储产品,Firebase Realtime Database对数组的查询支持有限,数组会被自动转换为数字索引的对象,容易导致查询逻辑异常甚至崩溃。
  • 类型不匹配:数据中id是数字类型,但你的代码里EqualTo("1001")传的是字符串,类型不兼容会引发查询错误。
  • 代码逻辑错误:回调里判断的是player.Child("code"),但数据里对应的字段是id,属于字段名写错;同时直接查询根节点(GetReference(""))容易导致数据解析混乱。

最优解决方案

1. 调整Firebase数据结构(关键)

将数组改为键值对对象存储,既保留可查询的id和product_name字段,又兼容Firebase的查询机制:

"products": {
  "product_1001": {
    "id": 1001,
    "price": "265$",
    "product_name": "dell",
    "type": "monitor"
  },
  "product_1002": {
    "id": 1002,
    "price": "320$",
    "product_name": "ibm",
    "type": "laptop"
  },
  "product_1003": {
    "id": 1003,
    "price": "542$",
    "product_name": "hp",
    "type": "workstation"
  }
}

2. 添加Firebase索引

在Firebase控制台的实时数据库规则中添加索引,确保查询高效执行:

{
  "rules": {
    "products": {
      ".indexOn": ["id", "product_name"]
    }
  }
}

3. 修正查询代码

按ID查询

public void GetProductById(int targetId)
{
    // 指向products节点,避免直接查询根节点
    var productsRef = FirebaseDatabase.DefaultInstance.GetReference("products");
    // EqualTo传入数字类型,与数据中的id类型匹配
    productsRef.OrderByChild("id").EqualTo(targetId).ValueChanged += OnProductByIdReceived;
}

private void OnProductByIdReceived(object sender, ValueChangedEventArgs e)
{
    if (e.Snapshot.Exists)
    {
        foreach (var productSnapshot in e.Snapshot.Children)
        {
            string productName = productSnapshot.Child("product_name").GetValue(true).ToString();
            Debug.Log($"找到产品:{productName}");
        }
    }
    else
    {
        Debug.Log("未找到对应ID的产品");
    }
}

按产品名称查询

public void GetProductByName(string targetName)
{
    var productsRef = FirebaseDatabase.DefaultInstance.GetReference("products");
    productsRef.OrderByChild("product_name").EqualTo(targetName).ValueChanged += OnProductByNameReceived;
}

private void OnProductByNameReceived(object sender, ValueChangedEventArgs e)
{
    if (e.Snapshot.Exists)
    {
        foreach (var productSnapshot in e.Snapshot.Children)
        {
            string productName = productSnapshot.Child("product_name").GetValue(true).ToString();
            string price = productSnapshot.Child("price").GetValue(true).ToString();
            Debug.Log($"找到产品:{productName},价格:{price}");
        }
    }
    else
    {
        Debug.Log("未找到对应名称的产品");
    }
}

注意事项

  • 调用查询后记得在合适的时机(比如场景销毁)移除事件监听,避免内存泄漏:
    private void OnDestroy()
    {
        var productsRef = FirebaseDatabase.DefaultInstance.GetReference("products");
        productsRef.ValueChanged -= OnProductByIdReceived;
        productsRef.ValueChanged -= OnProductByNameReceived;
    }
    
  • 如果你坚持使用原数组结构,必须确保根节点下只有产品数据,且EqualTo传入的类型与id一致(数字1001而非字符串"1001"),但这种结构在数据量增大后查询性能会急剧下降,不推荐。

内容的提问来源于stack exchange,提问作者Kouibia Ibrahim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 01:05:54