Skip to content

Do not fail on non-broadcast streams in subscriptions.dart #42

@dmytro-kashcheiev

Description

@dmytro-kashcheiev

Current implementation of subscriptions expects all streams that it receives from the FirebaseClient to be broadcast=true:

    if (!stream.isBroadcast) {
        throw ArgumentError(
            'All streams passed to an `Subscription` instance should be broadcast.'
        );
    }
    return stream;

This behavior should be updated. For some internal reasons, the most up-to-date implementation of the Firebase client for Android (FlutterFire) returns a non-broadcast stream. So at least in some cases, it's expected for Firebase client to return ordinary stream.

Probably spine-dart-client should be updated to convert stream if needed:

var controller = StreamController<String>.broadcast();
controller.addStream(stream);
var result = controller.stream;

or

 stream.asBroadcastStream();

From the dart point of view, there is a huge difference between single subscription/broadcast streams.

The main diff is not only the number of subscribers, but the buffering of messages "before" the listener appears. It means that a single-subscription stream won't lose data, while all events pushed to the broadcast stream before the listener is connected, will be lost.

The described issue with loss of the data leads to massive use of single-subscription streams exposed to read-related API in various libraries, including Firebase libraries.
In some cases, for example, in flutterfire-web, it's impossible to have a single-subscription stream as reading API for Firebase, and it returns a broadcast stream.

To resolve this issue, an investigation of the client-server API implementation is required.

  1. If there is no chance that data appear in the subscription before the listener — then it is should possible to accept both types of streams, and automatically convert them to broadcast streams.

  2. If data may appear in the subscription stream before the listener is connected — probably, some updates to the client implementation should be done to avoid such cases.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

📋 Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions