Skip to content

HTTPSCallable does not invoke completion blocks on the main thread #14653

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bdaz opened this issue Apr 4, 2025 · 9 comments · Fixed by #14667
Closed

HTTPSCallable does not invoke completion blocks on the main thread #14653

bdaz opened this issue Apr 4, 2025 · 9 comments · Fixed by #14667
Assignees

Comments

@bdaz
Copy link

bdaz commented Apr 4, 2025

Description

Issue: HTTPSCallable's callWithObject:completion does not invoke the completion block on the main thread.

Regression: This appears to be a regression from #14085.

Reproducing the issue

  1. Create an HTTPSCallable function.
  2. Invoke it with callWithObject:completion

Expected results: observe that the completion block is called on the main thread.
Actual results: the completion block is called on a background thread.

Firebase SDK Version

11.11.1

Xcode Version

16.2

Installation Method

CocoaPods

Firebase Product(s)

Functions

Targeted Platforms

iOS

Relevant Log Output

If using Swift Package Manager, the project's Package.resolved

No response

If using CocoaPods, the project's Podfile.lock

No response

@google-oss-bot
Copy link

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@bdaz
Copy link
Author

bdaz commented Apr 4, 2025

cc @ncooke3 @yakovmanshin

@ncooke3 ncooke3 self-assigned this Apr 4, 2025
@yakovmanshin
Copy link
Contributor

Seems like an unintended consequence of that old change.

On the other hand, as I was refactoring some Functions components last year, it never occurred to me that calling completion handlers on the main thread was even as little as an informal convention—more like a fortunate coincidence. In practice, I wouldn’t rely on this behavior in client code; though, of course, some sort of harmonization would be welcome (so far there’s only one method in the entire module that explicitly schedules completions on the main thread).

@ncooke3
Copy link
Member

ncooke3 commented Apr 4, 2025

@bdaz, as a workaround until a fix is released, you could use the previous release or wrap the contents of your callback in DispatchQueue.main.async {}

@ncooke3
Copy link
Member

ncooke3 commented Apr 8, 2025

I merged a fix with #14667. It should release in a few weeks (~week of April 22). Thanks for the report!

@bdaz
Copy link
Author

bdaz commented Apr 9, 2025

Thanks!

Seems like an unintended consequence of that old change.

On the other hand, as I was refactoring some Functions components last year, it never occurred to me that calling completion handlers on the main thread was even as little as an informal convention—more like a fortunate coincidence. In practice, I wouldn’t rely on this behavior in client code; though, of course, some sort of harmonization would be welcome (so far there’s only one method in the entire module that explicitly schedules completions on the main thread).

For what it's worth, it's definitely a convention in iOS programming to invoke completions on the main-thread unless otherwise documented. UIKit, CoreAnimation, Cocoa (for the most part), and many parts of Foundation are not thread-safe, and any code that could reasonably end up updating UI will need to trampoline back to main. As a result most libraries (including Firebase!) do this for clients, and if they don't, their documentation should note that completion blocks may be called from a background thread. Swift has of course made this more explicit with @MainActor annotations, which is nice. But I appreciate this being fixed!

@sergiocampama
Copy link
Contributor

Thanks for fixing this, I just found it today while upgrading to the latest version. Are there any updates on when 11.12 might be released?

@ncooke3
Copy link
Member

ncooke3 commented Apr 11, 2025

@sergiocampama, it's currently planned for the week of April 22. In the meantime, you could stay on the previous version, manually patch in the fix, or upgrade but wrap the contents of your callback in DispatchQueue.main.async {} Apologies for the inconvenience!

@sergiocampama
Copy link
Contributor

Yeah, figured I could do that. I'm on 10.29, I can wait a bit longer to not have to do those workarounds :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants