Non-nullable instance field '_db' must be initialized. (Documentation) - flutter

I'm try do something here but getting an error
NotesDBWorker.dart
class NotesDBWorker {
NotesDBWorker._();
static final NotesDBWorker db = NotesDBWorker._();
Database _db;
Future get database async {
// ignore: unnecessary_null_comparison
if (_db == null) {
_db = await init();
}
return _db;
}
}

If you want your variable to have a null state, you should declare it as nullable by adding a ? after the name of the type. Using late will result in a runtime LateInitializationError.
class NotesDBWorker {
NotesDBWorker._();
static final NotesDBWorker db = NotesDBWorker._();
Database? _db;
Future get database async {
if (_db == null) {
_db = await init();
}
return _db;
}
}
You should generally also not be suppressing analyzer warnings. They are there for a reason.

Related

how to initialize SQLite Database variable in my flutter app

I'm a beginner in flutter, i want to use SQlite database using sqflite package in my Flutter App, when I declare the _database variable with this syntax static Database _database; i got a compilation error saying that i must initialize _database, and when i use this syntax static Database? _database;, i have a compilation error under return _database saying A value of type 'Database?' can't be returned from the function 'database' because it has a return type of 'Future<Database>'. and when i put static late Database _database; i have an error in execution saying Error: LateInitializationError: Field '_database' has not been initialized.
my code is
class AnnonceDataBase {
AnnonceDataBase._();
static final AnnonceDataBase instance = AnnonceDataBase._();
static Database _database;
Future<Database> get database async {
if (_database != null) return _database;
_database = await initDB();
return _database;
}
}
I have modified it a bit but it works for you using a singleton to maintain the state of the database
class AnnonceDataBase {
AnnonceDataBase._();
static final AnnonceDataBase _instance = AnnonceDataBase._();
static Database? _database;
factory AnnonceDataBase() => _instance;
Future<Database> get database async {
if (_database != null) return _database!;
_database = await initDB();
return _database!;
}
Future<Database> initDB() async {
String table1 = "CREATE TABLE IF NOT EXISTS table1(id INTEGER PRIMARY KEY,key TEXT NOT NULL UNIQUE,name TEXT,phone NUMERIC)";
String table2 = "CREATE TABLE IF NOT EXISTS table2(id INTEGER PRIMARY KEY,key TEXT NOT NULL UNIQUE,name TEXT,phone NUMERIC)";
String path = await getDatabasesPath();
// Open the database and save the reference.
final Future<Database> database = openDatabase(
// Set the path to the database. Note: Using the `join` function of the
// plugin `path` is best practice to ensure the path is correct
// built for each platform.
p.join(path, 'admin.db'),
// When the database is first created, create a table to store data
onCreate: (db, version) {
db.execute(table1);
return db.execute(table2);
},
// Set the version. This runs the onCreate function and provides a
// path to perform updates and downgrades on the database.
version: 1,
);
return database;
}
}
You can use it like this
#override
void initState() {
AnnonceDataBase._instance.database; //Initialize when loading the application or in the singleton
super.initState();
}
Create a record
Future<void> addData() async {
Database database = AnnonceDataBase._database!;
database.transaction((txn) async {
await txn.rawInsert('INSERT INTO table1(id,key,name,phone) VALUES(?,?,?,?)', ["1", DateTime.now().toString(), "name", "+5555555"]);
});
}
Read all records
Future<void> readData() async {
Database database = AnnonceDataBase._database!;
List<Map> data = await database.rawQuery("SELECT * FROM table1");
debugPrint("data: $data");
}

how to initialize SQLite Database variable in flutter

I'm a beginner in flutter, i want to use SQlite database using sqflite package in my Flutter App, when I declare the _database variable with this syntax static Database _database; i got a compilation error saying that i must initialize _database, and when i use this syntax static Database? _database;, i have a compilation error under return _database saying A value of type 'Database?' can't be returned from the function 'database' because it has a return type of 'Future<Database>'.
my code is
class AnnonceDataBase {
AnnonceDataBase._();
static final AnnonceDataBase instance = AnnonceDataBase._();
static Database _database;
Future<Database> get database async {
if (_database != null) return _database;
_database = await initDB();
return _database;
}
}
Just use like this.
/// late variable initialization
static late Database _database;
Here is more insight why late keyword is used.
https://blog.gskinner.com/archives/2021/03/flutter-lazy-instantiation-with-the-late-keyword.html
Have Fun!
class AppData {
static const _dbName = '<Database-Name>';
static const _dbVersion = 1;
static const _tableName = '<Table-Name>';
AppData._();
static final AppData instance = AppData._();
static Database? _database;
Future<Database?> get database async {
if (_database != null) {
return _database;
}
_database = await _initializeDatabase();
return _database;
}
Future<Database> _initializeDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = join(directory.path, _dbName);
return await openDatabase(path, version: _dbVersion, onCreate: _onCreate);
}
Future _onCreate(Database db, int version) async {
try {
const createQuery = '''
CREATE TABLE $_tableName(
/// TODO : <Define table structure here using SQL Query>
);
''';
await db.execute(createQuery);
} catch (e) { }
}
}

A value of type 'Database?' can't be returned from the function 'db' because it has a return type of 'Future<Database>'

i am getting error
A value of type 'Database?' can't be returned from the function 'db' because it has a return type of 'Future'
for the code
class DatabaseHelper {
static final DatabaseHelper _instance = new DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
static Database? _db;
Future<Database> get db async {
if (_db != null) {
return _db;
}
_db = await initDb();
return _db;
}
DatabaseHelper.internal();
initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, "main.db");
var ourDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return ourDb;
}
void _onCreate(Database db, int version) async {
await db.execute(
"CREATE TABLE User(id INTEGER PRIMARY KEY, username TEXT, password TEXT)");
print("Table is created");
}
The issue is db isnot nullable type where _db is nullable. You can include ! while you've already checked null state.
Future<Database> get db async {
if (_db != null) {
return _db!;
}
_db = await initDb();
return _db!;
}
I recommend to check null-safety

how to avoid safety null

in this class while declaring the constructor Repository i get this error 'Non-nullable instance field '_database' must be initialized.
Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'' i added late but it doesn't work the same error while declaring the static Database _database .
this is the class Repository
import 'package:sqflite/sqflite.dart';
import 'package:todo/repositories/database_connection.dart';
class Repository {
DatabaseConnection _databaseConnection;
Repository() {
_databaseConnection = DatabaseConnection();
}
static Database _database;
Future<Database> get database async {
if (_database != null) return _database;
_database = await _databaseConnection.setDatabase();
return _database;
}
insertData(table, data) async {
var connection = await database;
return await connection.insert(table,data)
}
and this is the DatabaseConnection
class DatabaseConnection {
setDatabase() async {
var directory = await getApplicationDocumentsDirectory();
var path = join(directory.path, 'db_todo_sqflite');
var database =
await openDatabase(path, version: 1, onCreate: _onCreateDatabase);
return database;
}
_onCreateDatabase(Database database, int version) async {
await database.execute(
"CREATE TABLE categories(id INTEGER KEY , name TEXT , descrption TEXT");
}
}
Your database itself is nullable, so you add a ?
static Database? _database;
That makes the _database nullable, but in your getter you are returning a non nullable instance of Database.
The nullable instance would be Database?
Future<Database?> get database async {
...
}
If you are sure that the _database is initialized, and can't be null at that point you return the value, and tell dart that this value is never null.
static Database? _database;
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _databaseConnection.setDatabase();
return _database!;
}
Note the "!" at the return _database!
See also https://dart.dev/null-safety/understanding-null-safety
And https://dart.dev/tools/diagnostic-messages#unchecked_use_of_nullable_value
You are getting an error because
static Database _database is no nullable
Change the code to
static Database? _database
thank all for the response
this how i correct the code
import 'package:sqflite/sqflite.dart';
import 'package:todo/repositories/database_connection.dart';
class Repository {
DatabaseConnection? _databaseConnection;
Repository() {
_databaseConnection = DatabaseConnection();
}
static Database? _database;
Future<Database?> get database async {
if (_database != null) return _database;
_database = await _databaseConnection!.setDatabase();
return _database! ;
}
insertData(table, data) async {
var connection = await database;
return await connection!.insert(table, data);
}
}
You also can use the late modifier:
late DatabaseConnection _databaseConnection;
Just make sure you set this variable before you try to use it.

Non-nullable instance field must be initialized and Unhandled error LateInitializationError

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();
}
}
}
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!;
}