Repository: IO-Design-Team/hive_ce

Issue:
Problem with ColorAdapter migration
**Steps to Reproduce**
I'm migrating from Hive to Hive CE. I followed all the steps in the migration guide, but I'm having issues with Color.

I was using Hive's ColorAdapter:

`Hive.registerAdapter(ColorAdapter());`

Now I'm getting the error `Unhandled Exception: HiveError: Cannot read, unknown typeId: 232. Did you forget to register an adapter?`

**Code sample**
```
import 'package:flutter/material.dart';
import 'package:hive_ce_flutter/adapters.dart';
import 'package:virtualpet/utils/color_utils.dart';

class ConsoleData extends HiveObject {
  Color consoleColor;

  Color buttonsColor;

  Color labelsColor;

  String? imageNameLeftAssetPath;

  String? imageNameRightAssetPath;

  String? iconTopAssetPath;

  ConsoleData({
    this.consoleColor = Colors.white,
    this.buttonsColor = ColorUtils.defaultButtonsColor,
    this.labelsColor = ColorUtils.defaultLabelColor,
    this.imageNameLeftAssetPath,
    this.imageNameRightAssetPath,
    this.iconTopAssetPath,
  });

  ConsoleData clone() {
    return ConsoleData(
        consoleColor: consoleColor,
        imageNameLeftAssetPath: imageNameLeftAssetPath,
        imageNameRightAssetPath: imageNameRightAssetPath,
        iconTopAssetPath: iconTopAssetPath,
        buttonsColor: buttonsColor,
        labelsColor: labelsColor);
  }
}
```

And my initialization call:

`Hive..init(path)..registerAdapters()..registerAdapter(ColorAdapter());`

**Version**
 - Platform: iOS, Android, Mac, Windows, Linux, Web
 - Flutter version: 3.32.8
 - Hive version:  hive_ce: ^2.11.3  hive_ce_flutter: ^2.3.1



Discussion: Is that a custom color adapter?
You should be using `Hive.initFlutter` which registers the color adapter for you
Also the color adapter's type id is 200 so I'm not sure how that error is related
Tks @Rexios80 . I changed `Hive..init(path)..registerAdapters()..registerAdapter(ColorAdapter());` to `Hive..initFlutter(path)..registerAdapters();` and now the error changed to:

```
[ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: type 'Null' is not a subtype of type 'num' in type cast
#0      HiveColorAdapter.read (package:hive_ce_flutter/src/adapters/color_adapter.dart:93:21)
#1      ColorAdapter.read (package:hive_ce_flutter/src/adapters/color_adapter.dart:24:23)
#2      BinaryReaderImpl.read (package:hive_ce/src/binary/binary_reader_impl.dart:372:33)
```

The problem now is in color_adapter.dart from hive_ce_flutter lib
I need to see more code. Passing `path` into `initFlutter` is not the same as passing it into `init`. So who knows what data you are trying to read. Where is `path` coming from?
@Rexios80 perfect. I'll try to create some minimal code to try to reproduce the error and share it here, I just need a little time.
@Rexios80 Here is some minimal code I created:

**USING HIVE:**

```
dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.8
  path_provider: ^2.1.5
  hive: ^2.2.3
  hive_flutter: ^1.1.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.4.13
  hive_generator: ^2.0.1
```

```
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/adapters.dart';
import 'package:path_provider/path_provider.dart';
import 'package:testhive/simple_object.dart';

String dbName = "simpleObjects";
void main() async{
  Directory? dir;
  String? path;
  dir = await getApplicationDocumentsDirectory();
  path = dir.path;
  if (Platform.isWindows) {
    path = "$path/test";
  }
  Hive.init(path);
  Hive.registerAdapter(SimpleObjectAdapter());
  Hive.registerAdapter(ColorAdapter());
  runApp(const MyApp());
}


class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Color color = Colors.black;

  @override
  void initState() {
    super.initState();
    init();
  }

  void init() async{
    SimpleObject? simpleObject;
    //UNCOMMENT TO SAVE
    // simpleObject = SimpleObject(id: "1", color: Colors.red);
    // save(simpleObject);

    //UNCOMMENT TO LOAD
    // simpleObject = await load("1");

    setState(() {
      color = simpleObject?.color ?? Colors.grey;
    });
  }

  Future<SimpleObject?> load(String id) async{
    Box<SimpleObject> box = await openBox();
    return box.get(id);
  }

  Future<void> save(SimpleObject simpleObject) async {
    Box<SimpleObject> box = await openBox();
    return box.put(simpleObject.id, simpleObject);
  }

  Future<Box<T>> openBox<T>() async {
    await Hive.openBox<T>(dbName);
    return Hive.box<T>(dbName);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: HomePage(color: color,),
    );
  }
}

class HomePage extends StatefulWidget {
  final Color color;
  const HomePage({super.key, required this.color});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: widget.color,
    );
  }
}
```

```
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
part 'simple_object.g.dart';

@HiveType(typeId: 1)
class SimpleObject extends HiveObject{
  @HiveField(0)
  String id;
  @HiveField(1)
  Color color;

  SimpleObject({required this.id, required this.color});

}
```

**AFTER HIVE_CE MIGRATION:**
```
dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.8
  path_provider: ^2.1.5
  hive_ce: ^2.11.3
  hive_ce_flutter: ^2.3.1

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.4.13
  hive_ce_generator: ^1.9.3
```

```
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:hive_ce/hive.dart';
import 'package:hive_ce_flutter/adapters.dart';
import 'package:path_provider/path_provider.dart';
import 'package:testhive/hive/hive_registrar.g.dart';
import 'package:testhive/simple_object.dart';

String dbName = "simpleObjects";
void main() async{
  Directory? dir;
  String? path;
  dir = await getApplicationDocumentsDirectory();
  path = dir.path;
  if (Platform.isWindows) {
    path = "$path/test";
  }
  Hive..initFlutter(path)..registerAdapters();
  runApp(const MyApp());
}


class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Color color = Colors.black;

  @override
  void initState() {
    super.initState();
    init();
  }

  void init() async{
    SimpleObject? simpleObject;
    //UNCOMMENT TO SAVE
    // simpleObject = SimpleObject(id: "1", color: Colors.red);
    // save(simpleObject);

    //UNCOMMENT TO LOAD
    // simpleObject = await load("1");

    setState(() {
      color = simpleObject?.color ?? Colors.grey;
    });
  }

  Future<SimpleObject?> load(String id) async{
    Box<SimpleObject> box = await openBox();
    return box.get(id);
  }

  Future<void> save(SimpleObject simpleObject) async {
    Box<SimpleObject> box = await openBox();
    return box.put(simpleObject.id, simpleObject);
  }

  Future<Box<T>> openBox<T>() async {
    await Hive.openBox<T>(dbName);
    return Hive.box<T>(dbName);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: HomePage(color: color,),
    );
  }
}

class HomePage extends StatefulWidget {
  final Color color;
  const HomePage({super.key, required this.color});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: widget.color,
    );
  }
}
```

```
import 'package:flutter/material.dart';
import 'package:hive_ce/hive.dart';

class SimpleObject extends HiveObject{
  String id;
  Color color;

  SimpleObject({required this.id, required this.color});

}
```
You need to save at least one object using old hive then migrate to hive_ce.

**RESULT:**
It worked as expected, but I noticed that in this sample code I created now it is referencing/importing Color Adapter from the old hive:

`..\AppData\Local\Pub\Cache\hosted\pub.dev\hive_flutter-1.1.0\lib\src\adapters\color_adapter.dart`

In the code where I'm having problems, it's using ColorAdapter from the new hive_CE lib:
`..\AppData\Local\Pub\Cache\hosted\pub.dev\hive_ce_flutter-2.3.1\lib\src\adapters\color_adapter.dart`

This seems to be the problem: there is a conflict in formats
@Rexios80 I found a solution/workaround but I don't know if it's the best: I pasted the original Hive ColorAdapter code into the hive_adapters.g.dart file:

```
class ColorAdapter extends TypeAdapter<Color> {
  @override
  Color read(BinaryReader reader) => Color(reader.readInt());

  @override
  void write(BinaryWriter writer, Color obj) => writer.writeInt(obj.value);

  @override
  int get typeId => 200;
}
```

And the initialization looks like this:

```
import 'package:hive_ce_flutter/adapters.dart' hide ColorAdapter;
...
Hive..initFlutter(path)..registerAdapters()..registerAdapter(ColorAdapter(), override: true);
```

This way everything is working. My database is quite complex and the rest of the migration seemed successful, the problem was with Color
That is not a valid solution unfortunately. The reason there is a new color adapter is because `color.value` is deprecated and will be removed in the future. Can you please make a github repo instead of pasting the contents of every file in a comment?

I did some testing and can't see any issue in the code so I'm not sure what's going on with your data.
Hold on I think I know what it is

Fix patch:
diff --git a/hive_flutter/CHANGELOG.md b/hive_flutter/CHANGELOG.md
index 9a9dd017..3c405988 100644
--- a/hive_flutter/CHANGELOG.md
+++ b/hive_flutter/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.3.2
+
+- Fixes an issue with the `ColorAdapter` reading legacy color data
+
 ## 2.3.1
 
 - Fixes web compatibility check
diff --git a/hive_flutter/lib/src/adapters/color_adapter.dart b/hive_flutter/lib/src/adapters/color_adapter.dart
index d7830251..46627f7d 100644
--- a/hive_flutter/lib/src/adapters/color_adapter.dart
+++ b/hive_flutter/lib/src/adapters/color_adapter.dart
@@ -17,7 +17,14 @@ class ColorAdapter extends TypeAdapter<Color> {
 
   @override
   Color read(BinaryReader reader) {
-    if (reader.availableBytes == 8) {
+    final firstByte = reader.peekBytes(1)[0];
+
+    // `color.value` is 4 bytes long
+    // ints are written as 8 bytes
+    // Therefore the first byte of old color data is 0
+    // The first byte of new color data is the field count which is not 0
+    // Therefore if the first byte is 0, this is old color data
+    if (firstByte == 0) {
       // Support for reading data created by the old ColorAdapter
       return Color(reader.readInt());
     } else {
diff --git a/hive_flutter/pubspec.yaml b/hive_flutter/pubspec.yaml
index 9accc7a8..f7e41355 100644
--- a/hive_flutter/pubspec.yaml
+++ b/hive_flutter/pubspec.yaml
@@ -1,6 +1,6 @@
 name: hive_ce_flutter
 description: Extension for Hive. Makes it easier to use Hive in Flutter apps.
-version: 2.3.1
+version: 2.3.2
 homepage: https://github.com/IO-Design-Team/hive_ce/tree/main/hive_flutter
 
 environment:


Test patch:
diff --git a/hive_flutter/test/adapters/color_adapter_test.dart b/hive_flutter/test/adapters/color_adapter_test.dart
index 0a8a2c8c..d60f4466 100644
--- a/hive_flutter/test/adapters/color_adapter_test.dart
+++ b/hive_flutter/test/adapters/color_adapter_test.dart
@@ -21,6 +21,9 @@ void main() {
         // ignore: deprecated_member_use
         writer.writeInt(color.value);
 
+        // Write some garbage to the end of the buffer
+        writer.writeInt(0);
+
         final reader = BinaryReaderImpl(writer.toBytes(), registry);
         final readColor = ColorAdapter().read(reader);
         expect(readColor, color);