Skip to main content

Subscribing

In progress — not available yet

Real-time streaming is not enabled on accounts yet. See the overview for what to do instead.

Subscribing (example)

Any Firebase Realtime Database SDK works — iOS, Android, or web. This is the shape our iOS client uses:

// 1. Send the message (async) — capture nothing beyond the runId if you like.
try await restate.sendMessage(conversationKey: conversationId, text: userText)

// 2. Observe the streaming node for the in-flight assistant message.
let seq = currentAssistantSequence // from conversations/{id}/status → seq
let ref = database.reference()
.child("streaming").child(conversationId).child(String(seq))

let handle = ref.observe(.value) { snapshot in
guard let json = snapshot.value,
let data = decode(StreamingData.self, from: json) else { return }

let text = data.chunks
.compactMap { $0 }
.filter { $0.type == "STREAM_CHUNK_TYPE_TEXT" || $0.type == nil }
.map { $0.content }
.joined()
render(text) // update the bubble

if data.meta?.status == "complete" || data.meta?.status == "error" {
ref.removeObserver(withHandle: handle) // stop listening
}
}

Web (modular Firebase JS SDK) follows the same pattern — call onValue() on the streaming/{conversationId}/{seq} node.

When to Use Polling Instead

Streaming needs a Firebase client and RTDB access. If you only need the final answer — a backend job, a webhook handler, a simple script — polling conversation-state is simpler and requires nothing beyond your API key. Streaming and polling read the same underlying run; you can mix them.