Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter integrating Hive database with Riverpod

There is very easy way to use Hive key-value database on StatefulWidgets, for example:

class HookDemo extends StatefulWidget {
  @override
  _HookDemoState createState() => _HookDemoState();
}

class _HookDemoState extends State<HookDemo> {
  Box user;
  @override
  void initState() {
    super.initState();
    
    user = Hive.box<User>('user');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () {
            final _u = User()
                ..nameFamily = 'myname'
                ..mobileNumber = '123456789';
            _user!.add(_u);
            _u.save();
        },
        child: Icon(Icons.add),
      ),
      ...
    );
  }
}

here we defined Box user property and inside initState we implemented what's user such as user = Hive.box<User>('user');

after that we can use user without any problem and getting already opened error

now in this current application we used HookWidget and when we want to use Hive we get error as box already opened

main.dart:

Future<void> initHiveDriver() async {
  final appDocumentDirectory = await path_provider.getApplicationDocumentsDirectory();
  await Hive.initFlutter(appDocumentDirectory.path);

  await Hive.openBox<UserAdapter>('user');
}

Future<void> main() async {
    WidgetsFlutterBinding.ensureInitialized();
    ///...
    initHiveDriver();

    runApp(
      ProviderScope(observers: [
        Logger()
      ],
      child: MyApp()),
    );
}

how can i create a provider for Hive with Riverpod and use it into HookWidget?

like image 628
DolDurma Avatar asked Mar 24 '26 20:03

DolDurma


1 Answers

I am using Hive with Riverpod like this.

I am using a named constructor so I can await the openBox call.

final hiveProvider = FutureProvider<HiveDB>((_) => HiveDB.create());

class HiveDB {
  var _userBox;

  HiveDB._create() {}

  static Future<HiveDB> create() async {
    final component = HiveDB._create();
    await component._init();
    return component;
  }

  _init() async {
      Hive.registerAdapter(UserAdapter());
      this._userBox = await Hive.openBox<User>('user');
  }

  storeUser(User user) {
    this._userBox.put('user', user);
  }

  User getUser() {
    return this._userBox.get('user');
  }

}

Use in a ConsumerWidget:

class SomeWidget extends ConsumerWidget {

  Widget build(BuildContext context, WidgetRef ref) {
      final provider = ref.watch(hiveProvider).data?.value;

      ...
  }

}
like image 178
ccnrbrn Avatar answered Mar 26 '26 10:03

ccnrbrn