I am a complete flutter and sqflite beginner. I am trying to make my calendar events persist over app restarts so I am implementing an SQFlite database. However, I keep running into this error and have no idea what is causing it. I tried to debug this with Phind, a programming AI, but to no avail.
Error:
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'bool' is not a subtype of type 'int' in type cast
E/flutter ( 6428): #0 EventHandler.fromJson
event_info_model.dart:57
E/flutter ( 6428): #1 EventsDatabase.readAllEvents.<anonymous closure>
events_database.dart:95
E/flutter ( 6428): #2 MappedListIterable.elementAt (dart:_internal/iterable.dart:415:31)
E/flutter ( 6428): #3 ListIterator.moveNext (dart:_internal/iterable.dart:344:26)
E/flutter ( 6428): #4 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:189:27)
E/flutter ( 6428): #5 new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
E/flutter ( 6428): #6 new List.of (dart:core-patch/array_patch.dart:47:28)
E/flutter ( 6428): #7 ListIterable.toList (dart:_internal/iterable.dart:214:7)
E/flutter ( 6428): #8 EventsDatabase.readAllEvents
events_database.dart:96
E/flutter ( 6428): <asynchronous suspension>
E/flutter ( 6428): #9 _CalendarViewPageState.refreshEvents
calendar_view_page.dart:54
E/flutter ( 6428): <asynchronous suspension>
Database code:
class EventsDatabase {
static final EventsDatabase instance = EventsDatabase._init();
static Database? _database;
EventsDatabase._init();
Future<Database> get database async {
debugPrint("Getting database...");
if (_database != null) return _database!;
_database = await _initDB('events.db');
return _database!;
}
Future<Database> _initDB(String filePath) async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, filePath);
debugPrint("Database initialized. It is present at: $dbPath");
return await openDatabase(path, version: 1, onCreate: _createDB);
}
Future _createDB(Database db, int version) async {
final textType = 'TEXT NOT NULL';
final integerType = 'INTEGER NOT NULL';
final booleanType = 'INTEGER DEFAULT 0';
await db.execute('''
CREATE TABLE $eventsTable
(
'summary' $textType,
'description' $textType,
'startTime' $integerType,
'endTime' $integerType,
'isAllDay' $booleanType
)
''');
}
Future<void> create(NeatCleanCalendarEvent event) async {
debugPrint("The create function has been entered.");
final db = await instance.database;
await db.insert(eventsTable, EventHandler().toJson(event));
debugPrint(EventsDatabase.instance.toString());
debugPrint("The create function has been exited.");
}
Future<NeatCleanCalendarEvent?> readEvent(
String summary, DateTime startTime) async {
final db = await instance.database;
final maps = await db.query(
eventsTable,
columns: EventFields.values,
where: 'summary = ? AND startTime = ?',
whereArgs: [summary, startTime],
);
if (maps.isNotEmpty) {
final map = maps.first;
final modifiedMap = Map<String, Object?>.from(map);
modifiedMap['isAllDay'] =
(map['isAllDay'] == 1 ? true : false); // Convert to boolean
return EventHandler.fromJson(modifiedMap);
} else {
return null; // Return null if no matching event is found
}
}
Future<List<NeatCleanCalendarEvent>> readAllEvents() async {
final db = await instance.database;
final orderBy = 'startTime ASC';
final result = await db.query(
eventsTable,
orderBy: orderBy,
);
return result.map((json) {
final modifiedJson = Map<String, Object?>.from(json);
modifiedJson['isAllDay'] =
(json['isAllDay'] == 1 ? true : false); // Convert to boolean
return EventHandler.fromJson(modifiedJson);
}).toList();
}
Future<int> update(NeatCleanCalendarEvent event) async {
debugPrint("The update function has been entered.");
final db = await instance.database;
return db.update(
eventsTable,
EventHandler().toJson(event),
where: 'summary = ? AND startTime = ?',
whereArgs: [event.summary, event.startTime],
);
}
Future<int> delete(NeatCleanCalendarEvent event) async {
debugPrint("The delete function has been entered.");
final db = await instance.database;
return await db.delete(
eventsTable,
where: 'summary = ? AND startTime = ?',
whereArgs: [event.summary, event.startTime],
);
}
Future<void> close() async {
debugPrint("The close function has been entered.");
final db = await instance.database;
await db.close();
}
}
EventHandler class –
final String eventsTable = 'events';
class EventFields {
static final List<String> values = [
summary,
description,
startTime,
endTime,
isAllDay
];
static final String summary = 'summary';
static final String description = 'description';
static final String startTime = 'startTime';
static final String endTime = 'endTime';
static final String isAllDay = 'isAllDay'; // Add this line for the new field
}
class EventHandler {
Map<String, Object?> toJson(NeatCleanCalendarEvent event) => {
EventFields.summary: event.summary,
EventFields.description: event.description,
EventFields.startTime: event.startTime.millisecondsSinceEpoch,
EventFields.endTime: event.endTime.millisecondsSinceEpoch,
EventFields.isAllDay: event.isAllDay ? 1 : 0, // Convert to integer
};
static NeatCleanCalendarEvent fromJson(Map<String, Object?> json) =>
NeatCleanCalendarEvent(
json[EventFields.summary] as String,
description: json[EventFields.description] as String,
startTime: DateTime.fromMillisecondsSinceEpoch(
json[EventFields.startTime] as int),
endTime: DateTime.fromMillisecondsSinceEpoch(
json[EventFields.endTime] as int),
isAllDay:
(json[EventFields.isAllDay] as int) == 1, // Convert to boolean
);
}
2
Answers
I think you should retry with the AI tbh. I cannot find an error for the life of me. Try restarting from scratch if nothing works.
Your
booleanType
is an integer.That means you have to use integers instead of booleans (
1
fortrue
and0
forfalse
)Try this change