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

Unity中从Firebase实时数据库拉取数据填充表格失败排查求助

Firebase Realtime Database数据拉取与Unity表格填充问题排查

问题说明

尝试从Firebase Realtime Database的timetable节点拉取数据,填充到Unity自制表格中,但运行场景时表格未被填充,需排查代码问题并确认节点引用正确性。

数据库结构

Firebase Realtime Database结构
timetable节点下包含多个以数字命名的子节点,每个子节点包含fname、monday、tuesday、wednesday、thursday、friday字段。

原代码

using Firebase;
using Firebase.Database;
using System;
using UnityEngine;
using UnityEngine.UI;
using Firebase.Unity;

public class ScheduleRetriever : MonoBehaviour
{
    // Table GameObject
    public GameObject table;
    // Prefab for table rows
    public GameObject rowPrefab;

    private DatabaseReference mDatabaseRef;
    private void Start()
    {
        // Initialize Firebase
        FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
            var dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available)
            {
                // Get reference to the "timetable" node
                mDatabaseRef = FirebaseDatabase.DefaultInstance.GetReference("timetable");
                // Retrieve data from the "timetable" node
                mDatabaseRef.GetValueAsync().ContinueWith(task => {
                    if (task.IsCompleted && !task.IsCanceled && !task.IsFaulted)
                    {
                        DataSnapshot snapshot = task.Result;
                        // Iterate through the children of the snapshot
                        foreach (var idChild in snapshot.Children)
                        {
                            DataSnapshot idSnapshot = idChild.Value as DataSnapshot;
                            //DataSnapshot idSnapshot = idChild.Value as DataSnapshot;
                            Debug.LogError("wut ");
                            // Add the data to the table
                            AddDataToTable(idChild);
                        }
                    }
                    else
                    {
                        Debug.LogError("Data retrieval failed: " + task.Exception);
                    }
                });
            }
            else
            {
                Debug.LogError(
                  "Could not resolve all Firebase dependencies: " + dependencyStatus);
            }
        });
    }

    private void AddDataToTable(DataSnapshot idChild)
    {
        // Create a new row
        GameObject newRow = Instantiate(rowPrefab);
        // Set the parent of the new row to the table
        newRow.transform.SetParent(table.transform, false);
        // Get the text components of the new row
        Text[] rowTexts = newRow.GetComponentsInChildren<Text>();
        // Set the text of the first column to the "fname" value retrieved from Firebase
        rowTexts[0].text = idChild.Child("fname").Value.ToString();
        // Set the text of the second column to the "monday" value retrieved from Firebase
        rowTexts[1].text = idChild.Child("monday").Value.ToString();
        // Set the text of the third column to the "tuesday" value retrieved from Firebase
        rowTexts[2].text = idChild.Child("tuesday").Value.ToString();
        // Set the text of the fourth column to the "wednesday" value retrieved from Firebase
        rowTexts[3].text = idChild.Child("wednesday").Value.ToString();
        // Set the text of the fifth column to the "thursday" value retrieved from Firebase
        rowTexts[4].text = idChild.Child("thursday").Value.ToString();
        // Set the text of the sixth column to the "friday" value retrieved from Firebase
        rowTexts[5].text = idChild.Child("friday").Value.ToString();
    }
}

问题排查与修复

1. 节点引用确认

节点引用正确,FirebaseDatabase.DefaultInstance.GetReference("timetable")与数据库结构完全匹配。

2. 核心代码问题及修复

(1)后台线程操作UI

Firebase异步回调默认运行在后台线程,Unity UI操作必须在主线程执行,直接调用AddDataToTable会导致UI不更新。需替换ContinueWith为Firebase提供的ContinueWithOnMainThread,确保回调在主线程执行。

(2)无效类型转换

DataSnapshot idSnapshot = idChild.Value as DataSnapshot;是错误代码:idChild.Value返回的是数据值(如字典),而非DataSnapshot,且该行未被使用,直接删除即可。

(3)空值引用异常

若数据库中某个字段为null,调用.Value.ToString()会抛出异常,导致后续代码终止。需添加空值判断。

(4)调试日志不足

原日志仅输出无意义内容,需添加节点数量、子节点键值等日志,便于确认数据是否正确拉取。

修复后代码

using Firebase;
using Firebase.Database;
using UnityEngine;
using UnityEngine.UI;
using Firebase.Unity;

public class ScheduleRetriever : MonoBehaviour
{
    public GameObject table;
    public GameObject rowPrefab;

    private DatabaseReference mDatabaseRef;

    private void Start()
    {
        FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
            var dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available)
            {
                mDatabaseRef = FirebaseDatabase.DefaultInstance.GetReference("timetable");
                mDatabaseRef.GetValueAsync().ContinueWithOnMainThread(task => {
                    if (task.IsCompleted && !task.IsCanceled && !task.IsFaulted)
                    {
                        DataSnapshot snapshot = task.Result;
                        Debug.Log($"拉取到{timetable}节点子节点数量:{snapshot.ChildrenCount}");
                        
                        foreach (var idChild in snapshot.Children)
                        {
                            Debug.Log($"当前子节点键:{idChild.Key},数据:{idChild.Value}");
                            AddDataToTable(idChild);
                        }
                    }
                    else
                    {
                        Debug.LogError("数据拉取失败:" + task.Exception?.Message);
                    }
                });
            }
            else
            {
                Debug.LogError("无法解析Firebase依赖:" + dependencyStatus);
            }
        });
    }

    private void AddDataToTable(DataSnapshot idChild)
    {
        GameObject newRow = Instantiate(rowPrefab);
        newRow.transform.SetParent(table.transform, false);
        Text[] rowTexts = newRow.GetComponentsInChildren<Text>();

        // 空值处理,避免空引用异常
        rowTexts[0].text = idChild.Child("fname").Value?.ToString() ?? "无数据";
        rowTexts[1].text = idChild.Child("monday").Value?.ToString() ?? "无数据";
        rowTexts[2].text = idChild.Child("tuesday").Value?.ToString() ?? "无数据";
        rowTexts[3].text = idChild.Child("wednesday").Value?.ToString() ?? "无数据";
        rowTexts[4].text = idChild.Child("thursday").Value?.ToString() ?? "无数据";
        rowTexts[5].text = idChild.Child("friday").Value?.ToString() ?? "无数据";
    }
}

额外检查项

  • 确认table和rowPrefab已在Inspector中正确赋值,且rowPrefab的子物体包含6个Text组件,顺序与代码索引对应。
  • 检查Firebase数据库规则是否允许读取(测试阶段可临时设置为{ "rules": { ".read": true, ".write": true } })。
  • 查看Unity Console是否有权限、依赖相关报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:45:58