0
votes

I'm working on a Unity3D application connected to a Firebase backend. We're using Auth, Firestore and Storage, the connection to Firebase is working smoothly.

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.

I'm using the PutStreamAsync method as described in the docs. 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. Error codes: 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. 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. But when we try with 200mb files, memory goes way beyond that and clearly the OS kills the app.

This is what I see in the XCode log when the crash happens:

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. 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).

Is there anything I could do on my side or is this clearly a bug in the SDK? Will be trying to find alternatives in the meantime.