Skip to content

fix(FirebaseStorageUI): prevent crash with .progressiveLoad on Firebase Storage 9+#1352

Draft
demolaf wants to merge 2 commits into
mainfrom
fix/storage-progressive-load-crash
Draft

fix(FirebaseStorageUI): prevent crash with .progressiveLoad on Firebase Storage 9+#1352
demolaf wants to merge 2 commits into
mainfrom
fix/storage-progressive-load-crash

Conversation

@demolaf

@demolaf demolaf commented Jun 9, 2026

Copy link
Copy Markdown
Member

FIRStorageDownloadTask.fetcher was an internal property removed in Firebase Storage 9.0.0. Accessing it via the progress observer caused a crash when .progressiveLoad was passed as an option.

Guard with respondsToSelector: so the progressive decode path is skipped on Firebase 9+. Images still load to completion — only the in-flight progressive rendering is lost, since Firebase no longer exposes partial download data publicly.

Closes #1146
Closes #1114

@demolaf demolaf marked this pull request as draft June 9, 2026 16:35
@demolaf demolaf changed the base branch from main to feat/storage-ui-swift-spm June 9, 2026 16:35

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors FirebaseStorage imports and declarations to support Swift Package Manager (SPM) builds and avoid Clang module-scanner failures. It replaces @import FirebaseStorage with forward declarations in public headers and moves the actual imports and category declarations to implementation files. Additionally, it guards progressive decoding in FUIStorageImageLoader.m to prevent crashes on Firebase Storage 9+ where the internal GTMSessionFetcher was removed. Feedback suggests avoiding performSelector: in FUIStorageImageLoader.m to prevent ARC compiler warnings, recommending direct property access to task.fetcher instead, since the property is already declared in the class extension.

Comment on lines +134 to +135
if ([task respondsToSelector:@selector(fetcher)]) {
GTMSessionFetcher *fetcher = [task performSelector:@selector(fetcher)];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using performSelector: under ARC can trigger a compiler warning (-Warc-performSelector-leaks) because the compiler cannot statically verify the selector's memory management behavior.

Since fetcher is already declared in the class extension of FIRStorageTask (which FIRStorageDownloadTask inherits from) on line 45 of this file, the compiler is fully aware of the fetcher property. Therefore, you can safely access task.fetcher directly once you have guarded it with respondsToSelector:. This is cleaner, type-safe, and avoids any potential compiler warnings.

      if ([task respondsToSelector:@selector(fetcher)]) {
        GTMSessionFetcher *fetcher = task.fetcher;

@demolaf demolaf changed the base branch from feat/storage-ui-swift-spm to main June 9, 2026 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant