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
相关产品推荐
相关产品推荐

