firebase / firebase/firebase-ios-sdk
Functions: callable stream fails on the server's `: ping` heartbeat
- Dominant language
- C++
- Stars
- 6.7k
- Forks
- 1.8k
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 75
Description
### Description
`HTTPSCallable.stream()` throws `FunctionsError` `.dataLoss` ("Unexpected format for streamed response.") as soon as the server sends an SSE comment line. `firebase-functions` (7.x) writes `: ping\n\n` whenever a streaming `onCall` has been quiet for 30 seconds (`heartbeatSeconds`, default 30), so any callable that takes longer than that without emitting a chunk fails on iOS. The Node client and the web SDK are fine with it.
The parser in `Functions.swift` only accepts lines that start with `data:`:
```swift
for try await line in stream.lines {
guard line.hasPrefix("data:") else {
continuation.finish(throwing: FunctionsError(.dataLoss, ...))
return
}
```
Comment lines (`:` prefix) are part of the SSE spec and should be skipped. Same code on `main` today.
We ran into it with a function that proxies an image generation: nothing to stream for ~50 s, then the result. Every call over 30 s failed, the ones under 30 s worked. Setting `heartbeatSeconds: null` on the function works around it.
### Reproducing the issue
1. Deploy (or run in the emulator) a streaming callable that waits before sending anything:
```ts
export const slow = onCall(async (req, res) => {
await new Promise((r) => setTimeout(r, 40_000));
res.sendChunk("hello");
return "done";
});
```
2. Call it from iOS with `Functions.functions().httpsCallable("slow").stream()`.
3. After 30 s the stream fails with `Unexpected format for streamed response.`
### Firebase SDK Version
12.17.0
### Xcode Version
27.0 (27A5252f)
### Installation Method
Swift Package Manager
### Firebase Product(s)
Functions
### Targeted Platforms
iOS
### Relevant Log Output
```
Error Domain=com.firebase.functions Code=15 "Unexpected format for streamed response."
```
Contributor guide
Research direction
Start in Functions.swift at the parser loop over stream.lines, then reproduce with the slow streaming callable described in the issue. The fix is complete when SSE comment lines beginning with ':' are ignored, data lines still stream normally, and the delayed callable no longer fails with dataLoss.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- firebase, ios, swift
- Domain
- api, mobile
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 83/100