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

Unity WebGL中通过REST监听Firebase实时数据库更新

Unity WebGL通过Firebase REST实现实时数据监听

由于Firebase暂无官方Unity WebGL插件,使用REST方式时,可以通过**Server-Sent Events(SSE)**实现实时监听数据库值变化(比如聊天新消息、数据更新),这是Firebase RTDB REST API原生支持的实时方案。

核心思路

Firebase RTDB的REST接口支持通过listen=true参数开启SSE流,服务器会在数据发生变化时主动推送更新到客户端。在Unity WebGL中,我们需要借助JavaScript实现SSE客户端,再回调给C#代码处理业务逻辑。

具体实现步骤

1. 创建WebGL JavaScript插件

在Unity项目的Plugins/WebGL目录下新建FirebaseSSE.jslib文件,实现SSE的连接、消息监听和停止逻辑:

mergeInto(LibraryManager.library, {
    StartFirebaseListener: function(urlPtr, callbackPtr) {
        const url = Pointer_stringify(urlPtr);
        const callback = Pointer_stringify(callbackPtr);
        
        const eventSource = new EventSource(url);
        
        eventSource.onmessage = function(event) {
            const data = JSON.parse(event.data);
            // 推送的数据包含path和data字段,path表示变化的节点路径
            sendMessage("FirebaseListener", callback, JSON.stringify(data));
        };
        
        eventSource.onerror = function(error) {
            console.error("Firebase监听出错:", error);
            eventSource.close();
        };
        
        // 全局保存实例,方便后续停止监听
        window.firebaseEventSource = eventSource;
    },
    
    StopFirebaseListener: function() {
        if (window.firebaseEventSource) {
            window.firebaseEventSource.close();
            window.firebaseEventSource = null;
        }
    }
});

2. 编写C#监听脚本

创建FirebaseListener.cs脚本,挂载到场景中名为FirebaseListener的GameObject上,负责调用JS插件、处理回调:

using UnityEngine;
using System.Runtime.InteropServices;

public class FirebaseListener : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void StartFirebaseListener(string url, string callbackMethodName);
    
    [DllImport("__Internal")]
    private static extern void StopFirebaseListener();

    // 监听用户partyID变化
    public void StartListeningToPartyID(string localUserDbId, string authToken = "")
    {
        string baseUrl = $"https://rtdb.firebaseio.com/Users/{localUserDbId}/partyID/.json";
        string listenUrl = BuildListenUrl(baseUrl, authToken);
        
        #if UNITY_WEBGL && !UNITY_EDITOR
        StartFirebaseListener(listenUrl, "OnPartyIDUpdated");
        #endif
    }

    // 监听聊天消息新增/更新
    public void StartListeningToChatMessages(string chatId, string authToken = "")
    {
        string baseUrl = $"https://rtdb.firebaseio.com/Chats/{chatId}/messages/.json";
        string listenUrl = BuildListenUrl(baseUrl, authToken);
        
        #if UNITY_WEBGL && !UNITY_EDITOR
        StartFirebaseListener(listenUrl, "OnChatMessageUpdated");
        #endif
    }

    // 构造带监听参数的URL
    private string BuildListenUrl(string baseUrl, string authToken)
    {
        string url = $"{baseUrl}?listen=true";
        if (!string.IsNullOrEmpty(authToken))
        {
            url += $"&auth={authToken}";
        }
        return url;
    }

    // PartyID更新回调
    public void OnPartyIDUpdated(string jsonData)
    {
        var updateData = JsonUtility.FromJson<FirebaseUpdateData>(jsonData);
        if (updateData.path == "/")
        {
            // 初始数据或节点整体更新
            string newPartyID = updateData.data.ToString();
            Debug.Log($"PartyID更新为: {newPartyID}");
            // 在这里处理UI更新或业务逻辑
        }
    }

    // 聊天消息更新回调
    public void OnChatMessageUpdated(string jsonData)
    {
        var updateData = JsonUtility.FromJson<FirebaseUpdateData>(jsonData);
        if (updateData.path != "/")
        {
            // 子节点新增(比如新消息),path格式为"/<消息ID>"
            ChatMessage newMsg = JsonUtility.FromJson<ChatMessage>(updateData.data.ToString());
            Debug.Log($"收到新消息: {newMsg.content}");
            // 将新消息添加到聊天界面
        }
    }

    // 停止所有监听
    public void StopAllListening()
    {
        #if UNITY_WEBGL && !UNITY_EDITOR
        StopFirebaseListener();
        #endif
    }

    // 辅助序列化类
    [System.Serializable]
    private class FirebaseUpdateData
    {
        public string path;
        public object data;
    }

    [System.Serializable]
    private class ChatMessage
    {
        public string senderId;
        public string content;
        public long timestamp;
    }
}

3. 使用示例

在业务代码中调用监听方法:

// 假设已获取用户ID和认证令牌
string localUserDbId = "user123";
string authToken = "用户的Firebase ID令牌";

FirebaseListener listener = FindObjectOfType<FirebaseListener>();
// 监听partyID变化
listener.StartListeningToPartyID(localUserDbId, authToken);
// 监听聊天消息
listener.StartListeningToChatMessages("chatRoom001", authToken);

// 不需要监听时停止
// listener.StopAllListening();

注意事项

  • 认证处理:如果数据库规则要求用户认证,必须在URL中携带auth参数,值为用户的Firebase ID令牌(可通过Firebase Auth REST API获取)。
  • 错误与重连:JS代码中的onerror事件可添加重连逻辑,避免因网络波动导致监听中断。
  • 编辑器限制:WebGL JS插件仅在WebGL构建后生效,编辑器中可使用模拟数据测试业务逻辑。
  • 资源清理:页面切换或不需要监听时,务必调用停止方法关闭SSE连接,防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 01:30:56