Reputation: 185
I'm trying to create a database and store an API token for user login but I keep getting an error when the app builds/compiles:
Non-nullable instance field '_database' must be initialized
I've tried adding a late modifier as suggested which then throws:
E/flutter ( 6894): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Unhandled error LateInitializationError: Field '_database@637109567' has not been initialized. occurred in Instance of 'AuthenticationBloc'.
my user_db.dart
import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
final userTable = 'userTable';
class DatabaseProvider {
static final DatabaseProvider dbProvider = DatabaseProvider();
//non nullable error on _database
Database _database;
Future <Database> get database async {
print('before condition');
if (_database != null){
return _database;
}
_database = await createDatabase();
return _database;
}
createDatabase() async {
Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "User.db");
var database = await openDatabase(
path,
version: 1,
onCreate: initDB,
onUpgrade: onUpgrade,
);
return database;
}
void onUpgrade(
Database database,
int oldVersion,
int newVersion,
){
if (newVersion > oldVersion){}
}
void initDB(Database database, int version) async {
await database.execute(
"CREATE TABLE $userTable ("
"id INTEGER PRIMARY KEY, "
"username TEXT, "
"token TEXT "
")"
);
}
}
my AuthBloc.dart
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:meta/meta.dart';
import 'package:equatable/equatable.dart';
import 'package:times/repository/user_repository.dart';
import 'package:times/model/user_model.dart';
part 'authentication_event.dart';
part 'authentication_state.dart';
class AuthenticationBloc
extends Bloc<AuthenticationEvent, AuthenticationState> {
AuthenticationBloc({required this.userRepository})
: super(AuthenticationUnauthenticated())
;
final UserRepository userRepository;
@override
Stream<AuthenticationState> mapEventToState(
AuthenticationEvent event,
) async* {
if (event is AppStarted) {
final bool hasToken = await userRepository.hasToken();
if (hasToken) {
yield AuthenticationAuthenticated();
} else {
yield AuthenticationUnauthenticated();
}
}
if (event is LoggedIn) {
yield AuthenticationLoading();
await userRepository.persistToken(
user: event.user
);
yield AuthenticationAuthenticated();
}
if (event is LoggedOut) {
yield AuthenticationLoading();
await userRepository.deleteToken(id: 0);
yield AuthenticationUnauthenticated();
}
}
}
Upvotes: 0
Views: 3831
Reputation: 6395
The problem is being caused by this line
if (_database != null) {
You can't directly apply null check on a non-nullable variable and since it is a late
variable and you didn't initialize it, the null check will always keep throwing the error.
One way to fix this would be to make your _database
Nullable and instantiate it to null
, like this
Database? _database = null;
In order to avoid using the Nullable
type everywhere in code, you could modify your function to use the bang
operator (!
) like this,
Future <Database> get database async {
if (_database != null){
return _database!;
}
_database = await createDatabase();
return _database!;
}
Upvotes: 1