0

我在 Unity 中使用 Firebase 时遇到了一些问题。我正在使用 Unity 2020.2.0b5.3233 和 Firebase 应用和数据库 6.16.1。我以前没有这个错误,但现在出现了!我离开了 REST API,因为它没有数据库更改检测功能!我究竟做错了什么?

所以,这是我的代码:

public static void CheckInit()
    {
            FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("censored");
            reference = FirebaseDatabase.DefaultInstance.RootReference;
    }

    public static void GetLastID(GetidLastCallback callback)
    {
        CheckInit();
        reference.Child("LastID")
            .ValueChanged += (object sender2, ValueChangedEventArgs e2) =>
            {
                if (e2.Snapshot != null && e2.Snapshot.ChildrenCount > 0)
                {
                    callback(e2.Snapshot.Value as idLast);
                }
            };
    }
    [Serializable]
    public class idLast
    {
        public int id;
        public idLast(int id)
        {
            this.id = id;
        }
    }

这是我的错误:

System.InvalidCastException: Specified cast is not valid.
  at Database+<>c__DisplayClass16_0.<GetLastID>b__0 (System.Object sender2, Firebase.Database.ValueChangedEventArgs e2) [0x00017] in D:\UnityProjects\Troubles\Assets\Database\Database.cs:93 
  at Firebase.Database.Internal.InternalValueListener+<OnValueChangedHandler>c__AnonStorey0.<>m__0 () [0x00030] in Z:\tmp\tmp.iLpyWKOT2N\firebase\database\client\unity\proxy\InternalValueListener.cs:53 
  at Firebase.ExceptionAggregator.Wrap (System.Action action) [0x00000] in Z:\tmp\tmp.tpC7OdQUHa\firebase\app\client\unity\src\Platform\ExceptionAggregator.cs:112 
0x00007ff6bfab34ac (Unity) StackWalker::GetCurrentCallstack
0x00007ff6bfabb889 (Unity) StackWalker::ShowCallstack
0x00007ff6c0f68c0c (Unity) GetStacktrace
0x00007ff6c2000e43 (Unity) DebugStringToFile
0x00007ff6bfb28bb9 (Unity) DebugLogHandler_CUSTOM_Internal_Log
0x000001c361db5ecb (Mono JIT Code) (wrapper managed-to-native) UnityEngine.DebugLogHandler:Internal_Log (UnityEngine.LogType,UnityEngine.LogOption,string,UnityEngine.Object)
0x000001c361db5d0b (Mono JIT Code) UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
0x000001c361db5a90 (Mono JIT Code) UnityEngine.Logger:Log (UnityEngine.LogType,object)
0x000001c362be5bb5 (Mono JIT Code) UnityEngine.Debug:LogError (object)
0x000001c36291806b (Mono JIT Code) [FirebaseLogger.cs:99] Firebase.Platform.FirebaseLogger:LogMessage (Firebase.Platform.PlatformLogLevel,string) 
0x000001c362be5223 (Mono JIT Code) [ExceptionAggregator.cs:101] Firebase.ExceptionAggregator:LogException (System.Exception) 
0x000001c362a7da13 (Mono JIT Code) [ExceptionAggregator.cs:78] Firebase.ExceptionAggregator:ThrowAndClearPendingExceptions () 
0x000001c362a7d60b (Mono JIT Code) [FirebaseHandler.cs:218] Firebase.Platform.FirebaseHandler:Update () 
0x000001c362a7d443 (Mono JIT Code) [FirebaseMonoBehaviour.cs:45] Firebase.Platform.FirebaseMonoBehaviour:Update () 
0x000001c3629159e0 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
0x00007ff8c437de60 (mono-2.0-bdwgc) [mini-runtime.c:2812] mono_jit_runtime_invoke 
0x00007ff8c4302902 (mono-2.0-bdwgc) [object.c:2921] do_runtime_invoke 
0x00007ff8c430b95f (mono-2.0-bdwgc) [object.c:2968] mono_runtime_invoke 
0x00007ff6bf931184 (Unity) scripting_method_invoke
0x00007ff6bf929995 (Unity) ScriptingInvocation::Invoke
0x00007ff6bf8ecf04 (Unity) MonoBehaviour::CallMethodIfAvailable
0x00007ff6bf8ed00c (Unity) MonoBehaviour::CallUpdateMethod
0x00007ff6bedd3d78 (Unity) BaseBehaviourManager::CommonUpdate<BehaviourManager>
0x00007ff6bedddf4a (Unity) BehaviourManager::Update
0x00007ff6bf24292a (Unity) `InitPlayerLoopCallbacks'::`2'::UpdateScriptRunBehaviourUpdateRegistrator::Forward
0x00007ff6bf2241bc (Unity) ExecutePlayerLoop
0x00007ff6bf224293 (Unity) ExecutePlayerLoop
0x00007ff6bf22b259 (Unity) PlayerLoop
0x00007ff6c06277a1 (Unity) PlayerLoopController::UpdateScene
0x00007ff6c0625487 (Unity) Application::TickTimer
0x00007ff6c0f7237f (Unity) MainMessageLoop
0x00007ff6c0f762e1 (Unity) WinMain
0x00007ff6c2d70796 (Unity) __scrt_common_main_seh
0x00007ff90d187034 (KERNEL32) BaseThreadInitThunk
0x00007ff90e89cec1 (ntdll) RtlUserThreadStart

InvalidCastException: Specified cast is not valid.
Firebase.ExceptionAggregator.ThrowAndClearPendingExceptions () (at Z:/tmp/tmp.tpC7OdQUHa/firebase/app/client/unity/src/Platform/ExceptionAggregator.cs:78)
Firebase.Platform.FirebaseHandler.Update () (at Z:/tmp/tmp.tpC7OdQUHa/firebase/app/client/unity/src/Unity/FirebaseHandler.cs:217)
Firebase.Platform.FirebaseMonoBehaviour.Update () (at Z:/tmp/tmp.tpC7OdQUHa/firebase/app/client/unity/src/Unity/FirebaseMonoBehaviour.cs:45)
4

1 回答 1

0

我的猜测是这Snapshot.Value是一个原始类型(longdouble),所以它不能被强制转换为类型idLast。我敢打赌,您可以使用模式匹配来消除该错误,因此请替换:

callback(e2.Snapshot.Value as idLast);

和:

if (e2.Snapshot.Value is idLast id) {
    callback(id);
}

这首先检查是否.Value是 type idLast。然后,如果是,它会创建一个名为idtype的变量,idLast然后我将其传递给您现有的callback()函数。

尽管如此,我很确定这个值永远不会在你的代码片段中为真。那是因为Value 只能是 bool, string, long, double, IDictionary<string, object>, 或List<object>. 我不知道您的实时数据库的结构如何,但是如果您查看"LastId"Firebase 控制台中的节点,它要么是一个数字,要么包含一个名为的节点,该节点"id"有一个数字。因此,如果您只看到一个数字,您的代码应该是:

if (e2.Snapshot.Value is long id) {
    callback(new idLast(id));
}

否则你应该这样做:

if (e2.Snapshot.Value is IDictionary<string, object> dict) {
    long id;
    if (dict.TryGetValue("id", out id) {
        callback(new idLast(id));
    }
}

或者您可以使用以下方法从 Json 反序列化:

var id = JsonUtility.FromJson<idLast>(e2.Snapshot.GetRawJsonValue());
if (id != null) {
    callback(id);
}

.Snapshot最后,如果不为空,我提供的每条建议都有效。因此,保留该条件,但您可以删除 && e2.Snapshot.ChildrenCount > 0.

[编辑]

我注意到最后一项注意事项。你只有ValueChanged +=但从来没有ValueChanged -=。您应该缓存reference.Child("LastID")为变量并.ValueChanged在游戏结束时取消注册您的侦听器。如果您不这样做,您可能会在 Unity 编辑器中的播放和编辑模式之间遇到意外行为。

于 2020-10-29T16:07:02.503 回答