Flutter: Create object stream from Hive box

4,539

Solution 1

Use box.watch()

Next is a pseudo code just for example

Stream<User> listen() => box
      .watch(userID)
      .map(...) // somehow map your User
      .startWith(box.get(userID)); // initial value before any changes

PS If you will stuck in implementation - reach me in comments for help

PS 2: the startWith method is an extension provided by the rxdart package, so keep this in mind

Solution 2

By this issue I can assume there is no way to get the initial values on watch, it's possible just with listenable:

ValueListenableBuilder(
  valueListenable: Hive.box('settings').listenable(),
  builder: (context, box, widget) {
    return Center(
      child: Switch(
        value: box.get('darkMode', defaultValue: false),
        onChanged: (val) => box.put('darkMode', val),
      ),
    );
  },
)
Share:
4,539
Flik
Author by

Flik

Updated on December 22, 2022

Comments

  • Flik
    Flik over 1 year

    I am trying to access some user settings which are changed and accessed throughout the app. To do that, I am using Hive to retrieve user settings from a box. I would like to make that information accessible throughout the app by turning the UserSettings object retrieved from Hive.box('settings').get(userID) into a stream that will be fed into a StreamProvider.

    How would I go about turning Hive.box('settings').get(userID) into a Stream?

    Edit: Here is my code implementation so far:

    local_database.dart

    static Stream<UserSettings> get userSettings {
      return Hive.box('settings').watch(key: userID)?.map((boxEvent) {
        return boxEvent.value; // ========> value is always null from boxEvent
      });
    }
    
    static void saveUserSettings(UserSettings userPref) {
      Hive.box('settings').put(userID, userPref); 
    }
    

    main.dart

    class Launch extends StatefulWidget {
      @override
      _LaunchState createState() => _LaunchState();
    }
    
    class _LaunchState extends State<Launch> {
      @override
      Widget build(BuildContext context) {
        return MultiProvider(
          providers: [
            StreamProvider<User>.value(value: AuthService.user),
            StreamProvider<UserSettings>.value(value: LocalDatabase.userSettings),
          ],
          child: MaterialApp(
            title: 'MyApp',
            home: AuthWrapper(),
          ),
        );
      }
    

    settings.dart

    class SettingsScreen extends StatefulWidget {
      @override
      _SettingsScreenState createState() => _SettingsScreenState();
    }
    
    class _SettingsScreenState extends State<SettingsScreen> {
      UserSettings _settings;
    
      @override
      Widget build(BuildContext context) {
        _settings = Provider.of<UserSettings>(context);
    
        print(_settings.useLightTheme); // =====> Always returns null
    
        return Scaffold(
          appBar: AppBar(title: 'Settings'),
          body: Container()
        ),
      }
    }