title: Flutter use Stream or Future?
body: <p>I'm using Firestore database to store a list of objects. To retrieve them I use the <code>Stream</code> provided by the Firestore package, like this:</p>
  
  <pre><code> class FirestoreApi implements Api {
  
    FirestoreApi._();
    static final instance = FirestoreApi._();
  
    @override
    Stream&lt;List&lt;Job&gt;&gt; getJobList() {
      final path = "users/myUserId/jobs";
      final reference = Firestore.instance.collection(path);
      final snapshots = reference.snapshots();
  
      return snapshots.map((snapshot) =&gt; snapshot.documents.map(
        (snapshot) =&gt; Job(
          id: snapshot.data['uid'],
        name: snapshot.data['name']
       ),
      ).toList());
    }
  }
  </code></pre>
  
  <p>It implements an <code>abstract</code> class:</p>
  
  <pre><code>abstract class Api {
    Stream&lt;List&lt;Job&gt;&gt; getJobList();
  }
  </code></pre>
  
  <p>In my Repository class I call it like this:</p>
  
  <pre><code>class Repository {
    final FirestoreApi _firestoreApi = FirestoreApi.instance;
  
    Stream&lt;List&lt;job&gt;&gt; getJobList() =&gt; _firestoreApi.getJobList();
  }
  </code></pre>
  
  <p>Then in my BloC I call the Repository:</p>
  
  <pre><code>class JobBloc {
  
    final _repository = new Repository();
  
    Stream&lt;List&lt;Job&gt;&gt; getJobList() {
      try {
        return _repository.getJobList();
      } catch (e) {
        rethrow;
      } finally {}
    }
  }
  </code></pre>
  
  <p>And finally here is how I use it in my <code>Widget</code>:</p>
  
  <pre><code>Widget _buildBody(BuildContext context) {
    final JobBloc _jobBloc = Provider.of&lt;JobBloc&gt;(context);
  
    return StreamBuilder&lt;List&lt;Job&gt;&gt;(
    stream: _jobBloc.getJobList(),
    builder: (BuildContext context, AsyncSnapshot&lt;List&lt;Job&gt;&gt; snapshot) {
      if (snapshot.hasData) {
        return RefreshIndicator(
          child: JobList(snapshot.data),
          onRefresh: () =&gt; _jobBloc.refreshJobList(),
        );
      } else {
        if(snapshot.connectionState == ConnectionState.waiting) {
          return Center(child: CircularProgressIndicator());
        } else {
          return Center(child: Text("No data"));
        }
  
      }
    },
  );
   }
  </code></pre>
  
  <p>Until here everything works great and my <code>Widget</code> gets updated in real time when something is changed in the Firestore database.</p>
  
  <p>But now I want to go one step further. Lets say that maybe in the future I need to change my api implementation and use a REST api instead of Firestore. I want that my code is prepared for that. </p>
  
  <p>In that case, all the <code>getJobList()</code> methods should return a <code>Future&lt;List&lt;Job&gt;&gt;</code> since the API will not return a <code>Stream</code> (I don't know if that's possible).</p>
  
  <p>I would have another API class like this that now returns <code>Future&lt;List&lt;Job&gt;&gt;</code>:</p>
  
  <pre><code>class RestApi implements Api {
  
   RestApi._();
   static final instance = RestApi._();
  
   @override
   Future&lt;List&lt;Job&gt;&gt; getJobList() {
     //TODO: my rest api implementation
   }
  }
  </code></pre>
  
  <p>So the API <code>abstract</code> class would be modified like this:</p>
  
  <pre><code>abstract class Api {
    Future&lt;List&lt;Job&gt;&gt; getJobList();
  }
  </code></pre>
  
  <p>Here the updated Repository:</p>
  
  <pre><code>class Repository {
    final RestApi _restApi = RestApi.instance;
  
    Future&lt;List&lt;job&gt;&gt; getJobList() =&gt; _restApi.getJobList();
  }
  </code></pre>
  
  <p>And finally in my BloC I would <code>sink</code> the list returned by the API in a <code>StreamController</code> like this:</p>
  
  <pre><code>class JobBloc {
    final StreamController _jobController = StreamController&lt;List&lt;Job&gt;&gt;.broadcast();
  
    // retrieve data from stream
    Stream&lt;List&lt;Job&gt;&gt; get jobList =&gt; _jobController.stream;
  
    Future&lt;List&lt;Job&gt;&gt; getJobList() async {
      try {
        _jobController.sink.add(await _repository.getJobList());
      } catch (e) {
        rethrow;
      } finally {}
   }
  }
  </code></pre>
  
  <p>Now the question: I really like that Firestore returns a <code>Stream</code>, it makes my app to be updated in real time. But on the other hand, I would like that my architecture is consistent. </p>
  
  <p>Since I cannot make my REST api to return a <code>Stream</code>, I think the only way possible would be converting the Firebase <code>Stream</code> to a <code>Future</code> but then I would loose the real-time update feature.</p>
  
  <p>Something like this:</p>
  
  <pre><code>class FirestoreApi implements Api {
  
     FirestoreApi._();
     static final instance = FirestoreApi._();
  
      @override
      Future&lt;List&lt;Job&gt;&gt; getJobList() async {
        final path = "users/myUserId/jobs";
        final reference = Firestore.instance.collection(path);
        final snapshots = reference.snapshots();
  
      Stream&lt;List&lt;Job&gt;&gt; jobs = snapshots.map((snapshot) =&gt; snapshot.documents.map(
          (snapshot) =&gt; Job(
            id: snapshot.data['uid'],
            name: snapshot.data['name'],
          ),
         ).toList());
  
        List&lt;Job&gt; future = await jobs.first;
        return future;
  
       }
     }
  </code></pre>
  
  <p>Until now what I've researched is that using the <code>Future</code> will return only one response, so I will lose the real-time functionality. </p>
  
  <p>I would like to know if loosing the real-time feature would be worthy just to make the architecture consistent or if there is a better approach.</p>
  
  <p>Thanks in advance, any ideas or suggestion will be appreciated.</p>
  
  <p><strong>EDIT: Thanks a lot for your comments, I really appreciate them. I actually don't know which one should be marked as accepted answer since all of them have helped me a lot so I decided to give a positive vote to all of you. If anyone doesn't agree with that or this is not the right behaviour in Stackoverflow please let me know</strong> </p>