Skip to content

Functions: callable stream fails on the server's : ping heartbeat #16605

Description

@PSchmiedmayer

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::

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:
    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."

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions