Hive: Casting error on box reopen

Created on 24 Apr 2020  路  4Comments  路  Source: hivedb/hive

Hi! First of all amazing work with Hive, people love it on my team.

We've noticed a casting error when we reopen a box of type Map<String, dynamic>, values returns an _InternalLinkedHashMap<dynamic, dynamic> which is a map so that's fine, but the actual key, value types are missing. To be clear this only happens when the box gets closed and reopened. The actual exception is:

_CastError (type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>' in type cast)

Steps to Reproduce
You can reproduce using the code below.

Code sample

Box<Map<String, dynamic>> _getsBox;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Hive.initFlutter();
  _getsBox = await Hive.openBox<Map<String, dynamic>>('boxName');
  await _getsBox.put('key', {'itemKey': 'itemValue'});
  print('first call: ${_getsBox.values}');
  // success prints values
  await Hive.close();
  _getsBox = await Hive.openBox<Map<String, dynamic>>('boxName');
  print('second call: ${_getsBox.values}');
  // casting error
  runApp(MyApp());
}

Version

  • Platform: iOS, Android
  • Flutter version: channel stable, v1.12.13+hotfix.8
  • Hive version: hive: ^1.4.1 / hive_flutter: ^0.3.0+2

P.D.: Might be related to https://github.com/hivedb/hive/issues/260

problem

Most helpful comment

Unfortunately this is a limitation of the dart language. You can use

var box = await Hive.openBox<Map>('boxName');
var map = box.get("myMap").cast<String, dynamic>();

or you create an object which contains your box and generate a Hive adapter. The adapter will handle the casting.

All 4 comments

I have the same problem.

Found a work around:

You can get all the keys from the box and then iterate over it to get individual values like this:

Map<String, dynamic> obj = Map<String, dynamic>.from(box.get(key));

This works for me.

Unfortunately this is a limitation of the dart language. You can use

var box = await Hive.openBox<Map>('boxName');
var map = box.get("myMap").cast<String, dynamic>();

or you create an object which contains your box and generate a Hive adapter. The adapter will handle the casting.

@leisim What to do, if my map has nested maps? Is there a way to automatically cast all maps to Map?
I don't want to use adapters, because I already use JsonSerializable

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ProfileID picture ProfileID  路  4Comments

MyoLinOo picture MyoLinOo  路  3Comments

sergiyvergun picture sergiyvergun  路  4Comments

aminjoharinia picture aminjoharinia  路  3Comments

cachapa picture cachapa  路  4Comments