J. Pablo García
J. Pablo García

Reputation: 521

Flutter_bloc get updated data from firestore without UI event

I am using flutter to exchange firestore data from few devices.

If I use StreamBuilder everything works fine, but I do not like mixing business logic with UI. I would prefer using BLOC as pattern using flutter_bloc plugin.

introducir la descripción de la imagen aquí

But flutter_bloc works in this way:

Steps:

  1. Event ------------------------> New data BUT NO NEW UI EVENT

  2. Async Request

  3. Async Response

  4. State (mapEventToState)-------> ¿How do I get the new state?

As far as I do not have "UI Event" because firestore data is being updated from another device, I can not update State.

I could use something like this on the bloc constructor:

  Stream<QuerySnapshot> query;
  QuedadaBloc(){
    query = Firestore.instance.collection('my_collection').snapshots();
    query.listen((datos){  
      dispatch(Fetch()); // send fictitious UI event
    });
  }

But I think this is not the right way.

¿Any suggestion?

Many thanks.

J. Pablo.

Upvotes: 5

Views: 1588

Answers (1)

Mayur Dhurpate
Mayur Dhurpate

Reputation: 1292

The recommended way while using Flutter, Bloc and Firestore is to have the repository layer provide a stream of data from Firestore which can be subscribed by the Bloc in Bloc Constructor (or any other function; see this example).

Then, based on the changes in the stream, dispatch events when you receive new data from Firestore in the stream. The Bloc can handle the triggered dispatch event to change the State of the Application in a similar way when the changes in UI trigger the state change.

class SampleBloc extends Bloc<SampleEvent, SampleState> {
  final FirestoreRepo _firestoreRepo;

  StreamSubscription<?> _firestoreStreamSubscription;

  SampleBloc({@required FirestoreData firestoreData})
      : assert(firestoreRepo != null),
        _firestoreRepo = firestoreRepo;

// instead of '_mapXEventToState', the subscription can also be wired in 'SampleBloc' constructor function.  
Stream<TimerState> _mapXEventToState(XEvent xEvent) async* {
    // Runs a dispatch event on every data change in  Firestore 
    _firestoreStreamSubscription = _firestoreRepo.getDataStream().listen(
      (data) {
        dispatch(YEvent(data: data));
      },
    );
  }

References: Comment 1 and Comment 2 by Felix Angelov (felangel), flutter_bloc library creator in Bloc Gitter Chat

Upvotes: 4

Related Questions