简体   繁体   English

Firebase 云存储 - Unity - PutStreamAsync memory 大文件崩溃

[英]Firebase Cloud Storage - Unity - PutStreamAsync memory crash with large files

I'm working on a Unity3D application connected to a Firebase backend.我正在开发一个连接到 Firebase 后端的 Unity3D 应用程序。 We're using Auth, Firestore and Storage, the connection to Firebase is working smoothly.我们正在使用 Auth、Firestore 和 Storage,与 Firebase 的连接工作顺利。

When trying to upload a large file in iOS, a video recording of 200mb+, the app starts using all memory out of nowhere and crashes.当尝试在 iOS 中上传一个 200mb+ 的视频记录时,该应用程序突然开始使用所有 memory 并崩溃。

I'm using the PutStreamAsync method as described in the docs.我正在使用文档中描述的 PutStreamAsync 方法。 https://firebase.google.com/docs/storage/unity/upload-files#upload_from_a_local_file https://firebase.google.com/docs/storage/unity/upload-files#upload_from_a_local_file

I also tried using PutFileAsync but I'm getting a ErrorObjectNotFound, which makes no sense to me because it's an upload, not a download.我也尝试使用 PutFileAsync,但我得到了一个 ErrorObjectNotFound,这对我来说毫无意义,因为它是上传,而不是下载。 Error codes: https://firebase.google.com/docs/storage/unity/handle-errors错误代码: https://firebase.google.com/docs/storage/unity/handle-errors

Here's our code.这是我们的代码。 Just a simple use case, very similar to what's shown in the docs:只是一个简单的用例,与文档中显示的非常相似:

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 shows how memory spikes from 300mb to 1.4gb in a few seconds and it crashes. XCode 显示 memory 如何在几秒钟内从 300mb 飙升至 1.4gb 并崩溃。 When trying with a 100mb video, memory goes from 300 to 800mb and the upload succeeds, which confirms that the code is working and doing what's supposed to do.尝试使用 100mb 视频时,memory 从 300 变为 800mb 并且上传成功,这证实了代码正在工作并且正在做应该做的事情。 But when we try with 200mb files, memory goes way beyond that and clearly the OS kills the app.但是当我们尝试使用 200mb 文件时,memory 远远超出了这个范围,显然操作系统会杀死应用程序。

This is what I see in the XCode log when the crash happens:这是我在崩溃发生时在 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()

I'm using Unity 2020.3.18f1 LTS and Firebase SDK for Unity 8.10.1, installed through package manager.我正在为 Unity 8.10.1 使用 Unity 2020.3.18f1 LTS 和 Firebase SDK,通过 ZEFE90A8E604A7C840E88D03A67F6 管理器安装。 We can't upgrade because the newer versions are compiled by a version of XCode not yet supported by Unity Cloud Build (yeah that's really sad).我们无法升级,因为较新的版本是由 Unity Cloud Build 尚不支持的 XCode 版本编译的(是的,这真的很难过)。

Is there anything I could do on my side or is this clearly a bug in the SDK?有什么我可以做的吗,或者这显然是 SDK 中的错误? Will be trying to find alternatives in the meantime.在此期间将尝试寻找替代方案。

Finally I managed to effectively use PutFileAsync.最后,我设法有效地使用了 PutFileAsync。 Documentation is misleading.文档具有误导性。 The name of the parameter is "filePath" and in the docs for the Unity SDK there's a sample that uses a normal file path like "folder/file.png".参数的名称是“filePath”,在 Unity SDK 的文档中,有一个使用普通文件路径的示例,例如“folder/file.png”。

统一 SDK 文档

It turns out that it's not a path, it's an URI, and I had to prepend "file://" in order to make it work.事实证明,它不是路径,而是 URI,我必须在前面加上“file://”才能使其正常工作。 After that, I could upload 500mb files with no issues.之后,我可以毫无问题地上传 500mb 的文件。

In the API specification, under the "filePath" parameter, it explains that it is an URI.在 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 https://firebase.google.com/docs/reference/unity/class/firebase/storage/storage-reference#class_firebase_1_1_storage_1_1_storage_reference_1a0b6fee3e69ca0b004e8675f7d867d925

I wonder why they don't name it differently or add a proper example in the docs.我想知道他们为什么不以不同的方式命名它或在文档中添加适当的示例。 Lost hours with this.失去了几个小时。 Anyways, happy it's solved.无论如何,很高兴它已经解决了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM