【问题标题】:Firebase Cloud Storage - Unity - PutStreamAsync memory crash with large filesFirebase 云存储 - Unity - 大文件的 PutStreamAsync 内存崩溃
【发布时间】:2022-08-10 21:12:26
【问题描述】:

我正在开发一个连接到 Firebase 后端的 Unity3D 应用程序。 我们正在使用 Auth、Firestore 和 Storage,与 Firebase 的连接工作顺利。

当尝试在 iOS 中上传一个大文件(200mb+ 的视频录制)时,应用程序会突然开始使用所有内存并崩溃。

我正在使用文档中描述的 PutStreamAsync 方法。 https://firebase.google.com/docs/storage/unity/upload-files#upload_from_a_local_file

我也尝试使用 PutFileAsync,但我得到一个 ErrorObjectNotFound,这对我来说毫无意义,因为它是上传,而不是下载。 错误代码:https://firebase.google.com/docs/storage/unity/handle-errors

这是我们的代码。只是一个简单的用例,与文档中显示的非常相似:

public async Task<string> UploadTestVideo(TestExecution testExecution)
        {
            string videoPath = TestPathHelper.GetLocalVideoPath(testExecution);
            StorageReference folderRef = storageReference.Child($\"{StoragePathTestExecutions}/{testExecution.UID}/{StoragePathVideoRecordings}\");
            StorageReference fileRef = folderRef.Child(\"recording.mp4\");

            TVLog.Debug(Tag, $\"Upload video <{videoPath}> to CloudStorage at <{fileRef.Path}>\");
            try
            {
                MetadataChange newMetadata = new MetadataChange();
                newMetadata.ContentType = \"video/mp4\";

                //StreamReader stream = new StreamReader(videoPath);
                FileStream stream = File.OpenRead(videoPath);
                TVLog.Debug(Tag, \"Opened file stream for uploading...\");
                StorageMetadata metadata = await fileRef.PutStreamAsync(stream, newMetadata);
                TVLog.Debug(Tag, \"Finished uploading video...\");
                stream.Close();
                stream.Dispose();
                
                // Metadata contains file metadata such as size, content-type, and download URL.
                string md5Hash = metadata.Md5Hash;
                TVLog.Debug(Tag, \"video md5 hash = \" + md5Hash);
                return md5Hash;
            }
            catch(StorageException e){
                TVLog.Exception(Tag, $\"Exception uploading video {e.HttpResultCode} - {e.ErrorCode} - {e.Message}\");
                
                return null;
            }
        }

XCode 显示内存如何在几秒钟内从 300mb 飙升至 1.4gb 并崩溃。 尝试使用 100mb 视频时,内存从 300 变为 800mb 并且上传成功,这证实了代码正在工作并且正在做应该做的事情。 但是当我们尝试使用 200mb 的文件时,内存超出了这个范围,显然操作系统会杀死应用程序。

这是我在崩溃发生时在 XCode 日志中看到的内容:

WARNING -> applicationDidReceiveMemoryWarning()
2022-07-28 16:13:15.059747-0300 MyProject[84495:5466165] [xpc] <PKDaemonClient: 0x282907f00>: XPC error talking to pkd: Connection interrupted
WARNING -> applicationDidReceiveMemoryWarning()
2022-07-28 16:13:15.189228-0300 MyProject[84495:5466490] [ServicesDaemonManager] interruptionHandler is called. -[FontServicesDaemonManager connection]_block_invoke
WARNING -> applicationDidReceiveMemoryWarning()

我正在使用 Unity 2020.3.18f1 LTS 和 Firebase SDK for Unity 8.10.1,通过包管理器安装。我们无法升级,因为较新的版本是由 Unity Cloud Build 尚不支持的 XCode 版本编译的(是的,这真的很可悲)。

有什么我可以做的吗,或者这显然是 SDK 中的错误? 在此期间将尝试寻找替代方案。

    标签: firebase unity3d google-cloud-storage


    【解决方案1】:

    最后,我设法有效地使用了 PutFileAsync。 文档具有误导性。参数的名称是“filePath”,在 Unity SDK 的文档中,有一个使用普通文件路径的示例,例如“folder/file.png”。

    事实证明,它不是路径,而是 URI,我必须在前面加上“file://”才能使其正常工作。之后,我可以毫无问题地上传 500mb 的文件。

    在 API 规范中,在“filePath”参数下,它解释说它是一个 URI。 https://firebase.google.com/docs/reference/unity/class/firebase/storage/storage-reference#class_firebase_1_1_storage_1_1_storage_reference_1a0b6fee3e69ca0b004e8675f7d867d925

    我想知道他们为什么不以不同的方式命名它或在文档中添加适当的示例。失去了几个小时。无论如何,很高兴它已经解决了。

    【讨论】:

    • 关于 PutStreamAsync 的使用,没有找到解决方案。
    猜你喜欢
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 2019-08-08
    • 2019-02-16
    • 2018-05-31
    • 2020-05-20
    • 2012-01-28
    相关资源
    最近更新 更多