isar / hive

Lightweight and blazing fast key-value database written in pure Dart.
Apache License 2.0
4.07k stars 404 forks source link

Hive asks unknown typeId to be registered #242

Closed ampersanda closed 4 years ago

ampersanda commented 4 years ago

Steps to Reproduce

A newly fresh project and setup for Hive and I don't have an Adapter which has 33 typeId . This happens when I hot restart the current project and the way to fix this is by deleting the application. Here's short [Youtube Video] for (https://www.youtube.com/watch?v=l59ysgMz1uk&feature=youtu.be)

Here's the error

[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: HiveError: Cannot read, unknown typeId: 33. Did you forget to register an adapter?
#0      BinaryReaderImpl.read (package:hive/src/binary/binary_reader_impl.dart:322:11)
#1      BinaryReaderImpl.readFrame (package:hive/src/binary/binary_reader_impl.dart:273:26)
#2      FrameHelper.framesFromBytes (package:hive/src/binary/frame_helper.dart:17:26)
#3      FrameIoHelper.framesFromFile (package:hive/src/io/frame_io_helper.dart:41:12)
<asynchronous suspension>
#4      StorageBackendVm.initialize (package:hive/src/backend/vm/storage_backend_vm.dart:82:30)
<asynchronous suspension>
#5      BoxBaseImpl.initialize (package:hive/src/box/box_base_impl.dart:90:20)
#6      HiveImpl._openBox (package:hive/src/hive_impl.dart:90:17)
<asynchronous suspension>
#7      HiveImpl.openBox (package:hive/src/hive_impl.dart:111:18)
#8      main (package:untitled/main.dart:14:27)
<asynchronous suspension>
#9      _runMainZoned.<anonymous closure>.<anonymous closure> (dart<…>

Code sample note.dart

import 'package:hive/hive.dart';

part 'note.g.dart';

@HiveType(typeId: 1)
class Note {
  @HiveField(0)
  final String title;
  @HiveField(1)
  final String content;

  Note(this.title, this.content);
}

note.g.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'note.dart';

// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************

class NoteAdapter extends TypeAdapter<Note> {
  @override
  final typeId = 1;

  @override
  Note read(BinaryReader reader) {
    var numOfFields = reader.readByte();
    var fields = <int, dynamic>{
      for (var i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
    };
    return Note(
      fields[0] as String,
      fields[1] as String,
    );
  }

  @override
  void write(BinaryWriter writer, Note obj) {
    writer
      ..writeByte(2)
      ..writeByte(0)
      ..write(obj.title)
      ..writeByte(1)
      ..write(obj.content);
  }
}

main.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart';
import 'package:untitled/note.dart';

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

  Hive.init((await getApplicationDocumentsDirectory()).path);
//  Hive.initFlutter((await getApplicationDocumentsDirectory()).path);

  await Future.wait([Hive.openBox<Note>('notes')]);
  Hive.registerAdapter<Note>(NoteAdapter());

  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }

  @override
  void dispose() {
    Hive.box('notes').compact();
    Hive.close();
    super.dispose();
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key key}) : super(key: key);

  static const String routeName = '';

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    final Box<Note> noteBox = Hive.box('notes');

    return Scaffold(
      body: ValueListenableBuilder<Box<dynamic>>(
        valueListenable: noteBox.listenable(),
        builder: (_, Box<dynamic> noteBox, __) {
          return ListView.builder(
            itemBuilder: (_, int index) {
              return Text(noteBox.getAt(index).title);
            },
            itemCount: noteBox.length,
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          noteBox.add(Note('title', 'content'));
        },
        child: Icon(Icons.title),
      ),
    );
  }
}

Version

simc commented 4 years ago

You need to swap these two lines:

await Future.wait([Hive.openBox<Note>('notes')]);
Hive.registerAdapter<Note>(NoteAdapter());

The adapter needs to be registered before you open a box.

ampersanda commented 4 years ago

Thank you, it's fix this issue 🙃