title: Riverpod's StreamProvider yields StreamValue only once | Flutter & Hive
body: <p>I wrote a StreamProvider that I listen to right after startup to get all the information about a potentially logged in user. If there is no user, so the outcome would be null, the listener stays in loading state, so I decided to send back a default value of an empty user to let me know that the loading is done.
  I had to do this, because Hive's watch() method is only triggered when data changes, which it does not at startup.
  So after that, I want the watch() method to do its job, but the problem with that, are the following scenarios:</p>
  <ol>
  <li><p><strong>At startup: No user -</strong> Inserting a user -&gt; watch method is triggered -&gt; I get the inserted users data -&gt; Deleting the logged in user -&gt; watch method is not triggered.</p>
  </li>
  <li><p><strong>At startup: Full user -</strong> Deleting the user -&gt; watch method is triggered -&gt; I get an empty user -&gt; Inserting a user -&gt; watch method is not triggered.</p>
  </li>
  </ol>
  <p>After some time I found out that I can make use of all CRUD operations as often as I want to and the Hive's box does what it should do, but the watch() method is not triggered anymore after it got triggered <strong>once</strong>.</p>
  <p>The Streamprovider(s):</p>
  <pre><code>final localUsersBoxFutureProvider = FutureProvider&lt;Box&gt;((ref) async {
    final usersBox = await Hive.openBox('users');
    return usersBox;
  });
  
  final localUserStreamProvider = StreamProvider&lt;User&gt;((ref) async* {
    final usersBox = await ref.watch(localUsersBoxFutureProvider.future);
  
    yield* Stream.value(usersBox.get(0, defaultValue: User()));
    yield* usersBox.watch(key: 0).map((usersBoxEvent) {
      return usersBoxEvent.value == null ? User() : usersBoxEvent.value as User;
    });
  });
  </code></pre>
  <p>The Listener:</p>
  <pre><code>return localUserStream.when(
    data: (data) {
      if (data.name == null) {
        print('Emitted data is an empty user');
      } else {
        print('Emitted data is a full user');
      }
  
      return Container(color: Colors.blue, child: Center(child: Row(children: [
        RawMaterialButton(
          onPressed: () async {
            final globalResponse = await globalDatabaseService.signup({
              'email' : 'name@email.com',
              'password' : 'password',
              'name' : 'My Name'
            });
  
            Map&lt;String, dynamic&gt; jsonString = jsonDecode(globalResponse.bodyString);
            await localDatabaseService.insertUser(User.fromJSON(jsonString));
          },
          child: Text('Insert'),
        ),
        RawMaterialButton(
          onPressed: () async {
            await localDatabaseService.removeUser();
          },
          child: Text('Delete'),
        )
      ])));
    },
    loading: () {
      return Container(color: Colors.yellow);
    },
    error: (e, s) {
      return Container(color: Colors.red);
    }
  );
  </code></pre>
  <p>The CRUD methods:</p>
  <pre><code>Future&lt;void&gt; insertUser(User user) async {
      Box usersBox = await Hive.openBox('users');
      await usersBox.put(0, user);
      await usersBox.close();
    }
  
    Future&lt;User&gt; readUser() async {
      Box usersBox = await Hive.openBox('users');
      User user = usersBox.get(0) as User;
      await usersBox.close();
      return user;
    }
  
    Future&lt;void&gt; removeUser() async {
      Box usersBox = await Hive.openBox('users');
      await usersBox.delete(0);
      await usersBox.close();
    }
  </code></pre>
  <p>Any idea how I can tell the StreamProvider that the watch() method should be kept alive, even if one value already got emitted?</p>