I have a problem in my code that occurs error in lunching in database_helper.dart
database_helper.dart is one file in Sqlite storing data learning project and i faced this issue , i tried many solutions like uninstall app and install it again .
I have edited my question and added the other code called User.dart, I hope you find a solution to this problem, I'm really stuck
class DataBaseHelper {
static Database _db ;
final String userT = 'userT' ;
final String columnId = 'id' ;
final String columnUserName = 'username' ;
final String columnPassword = 'password' ;
final String columnAge = 'age' ;
final String columnCity = 'city' ;
Future<Database> get dbase async {
if(_db != null) {
return _db ;
}
_db = await intDB();
return _db ;
}
intDB() async {
Directory docDirectory = await getApplicationDocumentsDirectory() ;
String path = join(docDirectory.path , 'myDB.db') ;
var myOwnDB = await openDatabase(path , version: 1 , onCreate: _onCreate ) ;
return myOwnDB ;
}
void _onCreate(Database db , int newVersion) async {
var sql = 'CREATE TABLE $userT ($columnId INTEGER PRIMARY KEY ,'
' $columnUserName TEXT , $columnPassword TEXT , $columnCity TEXT , $columnAge INTEGER)' ;
await db.execute(sql) ;
}
Future<int> saveInfo(User user) async {
var dbClient = await dbase ;
int result = await dbClient.insert('$userT', user.toMap()) ;
return result ;
}
Future<List> getInfo() async {
var dbClient = await dbase ;
var sql = 'SELECT * FROM $userT' ;
List result = await dbClient.rawQuery(sql) ;
return result.toList() ;
}
Future<int> getCount() async {
var dbClient = await dbase ;
var sql = 'SELECT COUNT(*) FROM $userT' ;
return Sqflite.firstIntValue( await dbClient.rawQuery(sql) ) ;
}
Future<User> getUser(int id) async {
var dbClient = await dbase ;
var sql = 'SELECT * FROM $userT WHERE $columnId = $id' ;
var result = await dbClient.rawQuery(sql) ;
if(result.length == 0) return null ;
return new User.fromMap(result.first) ;
}
Future<int> deleteUser(int id) async {
var dbClient = await dbase ;
return await dbClient.delete(userT , where: '$columnId = ?' , whereArgs: [id] ) ;
}
Future<int> updateUser(User user) async {
var dbClient = await dbase ;
return await dbClient.update(userT , user.toMap() , where: '$columnId = ?' , whereArgs: [user.id] ) ;
}
Future closeDb() async {
var dbClient = await dbase ;
return await dbClient.close() ;
}
}
and there is the file that called User.dart
class User {
String userName ;
String password ;
String userCity ;
int userAge ;
int id ;
User(this.userName , this.password , this.userCity , this.userAge ) ;
User.map(dynamic obj){
this.userName = obj['username'] ;
this.password = obj['password'] ;
this.userAge = obj['age'] ;
this.userCity = obj['city'] ;
this.id = obj['id'] ;
}
String get _uName => userName ;
String get _pass => password ;
String get _uCity => userCity ;
int get _uAge => userAge ;
int get _uId => id ;
Map<String , dynamic> toMap() {
var map = new Map<String , dynamic>() ;
map['username'] = _uName ;
map['password'] = _pass ;
map['city'] = _uCity ;
map['age'] = _uAge ;
if(id != null){
map['id'] = _uId ;
}
return map ;
}
User.fromMap(Map<String , dynamic>map) {
this.userName = map['username'] ;
this.password = map['password'] ;
this.userAge = map['age'] ;
this.userCity = map['city'] ;
this.id = map['id'] ;
}
}
and this is the error log
E/flutter ( 3969): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
E/flutter ( 3969): #0 new User.map (package:was17savesqllite/model/user.dart:14:25)
E/flutter ( 3969): #1 main (package:was17savesqllite/main.dart:16:22)
E/flutter ( 3969): <asynchronous suspension>
E/flutter ( 3969): #2 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:216:25)
E/flutter ( 3969): #3 _rootRun (dart:async/zone.dart:1124:13)
E/flutter ( 3969): #4 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 3969): #5 _runZoned (dart:async/zone.dart:1516:10)
E/flutter ( 3969): #6 runZoned (dart:async/zone.dart:1500:12)
E/flutter ( 3969): #7 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:208:5)
E/flutter ( 3969): #8 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
E/flutter ( 3969): #9 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)
E/flutter ( 3969):
im really stuck here in tutorial , can any one help me plz ?
Looks like data types in your dynamic result does not match User object try casting
//inside
User.fromMap(Map<String , dynamic>map) {
this.userAge = int.parse(map['age'].toString());
this.id = int.parse(map['id'].toString()) ;
}
Related
"The non-nullable variable '_db' must be initialized. Try adding an initializer expression"
Could anyone help me with this non-nullable error?
I am using flutter to make an android app and while using the 'sqflite' and making a database, this error pops up I don't know how to really fix this
Here is my Code below,
I am using the last version of Flutter & Dart,
import 'dart:io';
import 'package:newtodoapp/taskmodel.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseHelper {
static final DatabaseHelper instance = DatabaseHelper._instance();
static Database _db;
DatabaseHelper._instance();
String tasksTable = 'task_table';
String colId = 'id';
String colTitle = 'title';
String colDate = 'date';
String colPriority = 'priority';
String colStatus = 'status';
// Task Tables
// Id | Title | Date | Priority | Status
// 0 '' '' '' 0
// 2 '' '' '' 0
// 3 '' '' '' 0
Future<Database> get db async {
if (_db == null) {
_db = await _initDb();
}
return _db;
}
Future<Database> _initDb() async {
Directory dir = await getApplicationDocumentsDirectory();
String path = dir.path + '/todo_list.db';
final todoListDb =
await openDatabase(path, version: 1, onCreate: _createDb);
return todoListDb;
}
void _createDb(Database db, int version) async {
await db.execute(
'CREATE TABLE $tasksTable($colId INTEGER PRIMARY KEY AUTOINCREMENT,'
' $colTitle TEXT, $colDate TEXT, $colPriority TEXT, $colStatus INTEGER)',
);
}
Future<List<Map<String, dynamic>>> getTaskMapList() async {
Database db = await this.db;
final List<Map<String, dynamic>> result = await db.query(tasksTable);
return result;
}
Future<List<Task>> getTaskList() async {
final List<Map<String, dynamic>> taskMapList = await getTaskMapList();
final List<Task> taskList = [];
taskMapList.forEach((taskMap) {
taskList.add(Task.fromMap(taskMap));
});
taskList.sort((taskA, taskB) => taskA.date.compareTo(taskB.date));
return taskList;
}
Future<int> insertTask(Task task) async {
Database db = await this.db;
final int result = await db.insert(tasksTable, task.toMap());
return result;
}
Future<int> updateTask(Task task) async {
Database db = await this.db;
final int result = await db.update(
tasksTable,
task.toMap(),
where: '$colId = ?',
whereArgs: [task.id],
);
return result;
}
Future<int> deleteTask(int id) async {
Database db = await this.db;
final int result = await db.delete(
tasksTable,
where: '$colId = ?',
whereArgs: [id],
);
return result;
}
}
declare your variable like this.
static Database? _db;
I am trying to list user messages in GMail Inbox.
$client = $this->getClient();
$service = new \Google_Service_Gmail($client);
$opt_param = array('labelIds' => 'INBOX');
$messagesResponse = $service->users_messages->listUsersMessages($user, $opt_param);
for ($i = 0; $i < $total; $i++) {
$messageToGet = ($messagesResponse->messages[$i]->id);
$message = $service->users_messages->get($user, $messageId);
$names = array_column($message->payload->headers, 'name');
$values = array_column($message->payload->headers, 'value');
$mail = array_combine($names, $values);
$senderMail = explode("<", $mail['From']);
if (count($senderMail) == 1) {
if (strpos($senderMail[0], '#') !== false) {
$senderName = [];
$domain[0] = substr($senderMail[0], strpos($senderMail[0], "#") + 1);
} else {
Log::info('Sender email could not be found');
return;
}
} else {
$senderName = [];
if ($senderMail[0] != "") {
$senderName = $senderMail[0];
$senderName = explode(" ", $senderName);
}
$senderMail = explode(">", $senderMail[1]);
$domain = explode("#", $mail['From']);
$domain = explode(">", $domain[1]);
}
...
}
When I tried to fetch 'From' from this $message response, it is throwing an undefined index error while fetching response for a message.
Notice: Notice (8): Undefined index: From in [File]
When I tried to debug the messages response return by the google api-php client, it resulted as below for all the messages
[16] => Google\Service\Gmail\MessagePartHeader Object
(
[name] => From
[value] => "Firstname Lastname" <firstname.lastname#gmail.com>
[internal_gapi_mappings:protected] => Array
(
)
[modelData:protected] => Array
(
)
[processed:protected] => Array
(
)
)
For one message, it returned
[16] => Google\Service\Gmail\MessagePartHeader Object
(
[name] => FROM
[value] => noreply#<domain>.org
[internal_gapi_mappings:protected] => Array
(
)
[modelData:protected] => Array
(
)
[processed:protected] => Array
(
)
)
Can anyone kindly let me know why the value of [name] key differs from From to FROM? Are there any more formats for the [name] key?
Thanks in Advance.
I was trying to build an app that takes in the Title, Date, Link, Priority level and then displays them using Flutter and SQLite.
I originally built it without 'link' and it was working perfectly, but when I added the filed 'link' it gives me this error:
E/flutter ( 8491): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: DatabaseException(table task_table has no column named link (code 1): , while compiling: INSERT INTO task_table (title, date, link, priority, status) VALUES (?, ?, ?, ?, ?)
E/flutter ( 8491): #################################################################
E/flutter ( 8491): Error Code : 1 (SQLITE_ERROR)
E/flutter ( 8491): Caused By : SQL(query) error or missing database.
E/flutter ( 8491): (table task_table has no column named link (code 1): , while compiling: INSERT INTO task_table (title, date, link, priority, status) VALUES (?, ?, ?, ?, ?))
E/flutter ( 8491): #################################################################) sql 'INSERT INTO task_table (title, date, link, priority, status) VALUES (?, ?, ?, ?, ?)' args [math, 2021-04-28T00:00:00.000, google, Medium, 0]}
The code associated with this is distributed in two files: a database helper file that basically stores all the functions for database management
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:todo/models/task_model.dart';
class DatabaseHelper {
static final DatabaseHelper instance = DatabaseHelper._instance();
static Database _db;
DatabaseHelper._instance();
String taskTable = 'task_table';
String colId = 'id';
String colTitle = 'title';
String colDate = 'date';
String colLink = 'link';
String colPriority = 'priority';
String colStatus = 'status';
// task tables
// Id | Title | Date | Link | Priority | Status
// 0 '' '' '' ''
// 2 '' '' '' ''
// 3 '' '' '' ''
Future<Database> get db async {
if (_db == null) {
_db = await _initDb();
}
return _db;
}
Future<Database> _initDb() async {
Directory dir = await getApplicationDocumentsDirectory();
String path = dir.path + 'todo_list.db';
final todoListDb =
await openDatabase(path, version: 1, onCreate: _createDb);
return todoListDb;
}
void _createDb(Database db, int version) async {
await db.execute(
'CREATE TABLE $taskTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, $colTitle TEXT, $colDate TEXT, $colLink TEXT, $colPriority TEXT, $colStatus INTEGER)');
}
Future<List<Map<String, dynamic>>> getTaskMapList() async {
Database db = await this.db;
final List<Map<String, dynamic>> result = await db.query(taskTable);
return result;
}
Future<List<Task>> getTaskList() async {
final List<Map<String, dynamic>> taskMapList = await getTaskMapList();
final List<Task> taskList = [];
taskMapList.forEach((taskMap) {
taskList.add(Task.fromMap(taskMap));
});
taskList.sort((taskA, taskB) => taskA.date.compareTo(taskB.date));
return taskList;
}
Future<int> insertTask(Task task) async {
Database db = await this.db;
final int result = await db.insert(taskTable, task.toMap());
return result;
}
Future<int> updateTask(Task task) async {
Database db = await this.db;
final int result = await db.update(taskTable, task.toMap(),
where: '$colId = ?', whereArgs: [task.id]);
return result;
}
Future<int> deleteTask(int id) async {
Database db = await this.db;
final int result =
await db.delete(taskTable, where: '$colId = ?', whereArgs: [id]);
return result;
}
}
And the second file is a database model file, which contains the database creation etc. :
class Task {
int id;
String title;
DateTime date;
String link;
String priority;
int status; // 0 - complete, 1- complete
Task({
this.title,
this.date,
this.link,
this.priority,
this.status,
});
Task.withId({
this.id,
this.title,
this.date,
this.link,
this.priority,
this.status,
});
Map<String, dynamic> toMap() {
final map = Map<String, dynamic>();
if (id != null) {
map['id'] = id;
}
map['title'] = title;
map['date'] = date.toIso8601String();
map['link'] = link;
map['priority'] = priority;
map['status'] = status;
return map;
}
factory Task.fromMap(Map<String, dynamic> map) {
return Task.withId(
id: map['id'],
title: map['title'],
date: DateTime.parse(map['date']),
link: map['link'],
priority: map['priority'],
status: map['status']);
}
}
This is my first time working with databases in flutter so any feedback would be greatly appreciated. Thank you
The error says that you don't have the column available in the table. The problem is that the db is not created every time you start the app. There are two solutions to your problem here:
For debug purposes, just delete the app and re-run the code, this will regenerate the database with the correct columns. WARNING: this is just for debug only, not for production.
For production, when you add changes on database, you have to increase the database version, in your case from 1 to let's say 2. Next, the openDatabase method has a parameter onUpgrade that will be called when the database version is upgraded, in your case from 1 to 2, here you'll have to run additional sql commands to update your table. Something like this:
await openDatabase(path, version: 1, onCreate: _createDb, onUpgrade: (db, old, newVersion) async {
if(old < 2) {
await db.execute("ALTER TABLE task_table ADD link TEXT");
}
});
Also do not forget to update your create table statement to add your new column there.
One scenario would be that you don't want to save the link in the db, in this case you'll have to remove it from json serialization (your toMap method) .
I was making an app and it keeps showing an error the method was called on null. When I looked up for answers it was specified that this occurs when method is not declared but in my case method has been already declared.
Due to this error I am not able to save data in my app.
initialiseDatabase is the function it states as called on null.
Here is the code-
static DatabaseHelper _databaseHelper; // singleton
static Database _database;
String noteTable = 'note_Table';
String colId = 'id';
String colTitle = 'title';
String colDescription = 'description';
String colPriority = 'priority';
String colDate = 'date';
DatabaseHelper._createInstance();// named constructor to create dbms helper
factory DatabaseHelper(){
if(DatabaseHelper == null) {
_databaseHelper = DatabaseHelper._createInstance();
}
return _databaseHelper;
}
Future<Database> get database async{
if(_database == null){
_database = await initializeDatabase();
}
return _database;
}
Future<Database> initializeDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'notes.db';
var notesDatabase = await openDatabase(path, version: 1, onCreate: _createDb);
return notesDatabase;
}
void _createDb(Database db, int newVersion) async{
await db.execute('CREATE TABLE $noteTable($colId INTEGER PRIMARY KEY AUTOINCREMENT, $colTitle TEXT.'
'$colDescription TEXT, $colPriority INTEGER, $colDate TEXT');
}
// Fetch Operation: Get all note objects from database
Future<List<Map<String, dynamic>>> getNoteMapList() async {
Database db = await this.database;
// var result = await db.rawQuery('SELECT * FROM $noteTable order by $colPriority ASC');
var result = await db.query(noteTable, orderBy: '$colPriority ASC');
return result;
}
// Insert Operation: Insert a Note object to database
Future<int> insertNote(Note note) async {
Database db = await this.database;
var result = await db.insert(noteTable, note.toMap());
return result;
}
// Update Operation: Update a Note object and save it to database
Future<int> updateNote(Note note) async {
var db = await this.database;
var result = await db.update(noteTable, note.toMap(), where: '$colId = ?', whereArgs: [note.id]);
return result;
}
// Delete Operation: Delete a Note object from database
Future<int> deleteNote(int id) async {
var db = await this.database;
int result = await db.rawDelete('DELETE FROM $noteTable WHERE $colId = $id');
return result;
}
// Get number of Note objects in database
Future<int> getCount() async {
Database db = await this.database;
List<Map<String, dynamic>> x = await db.rawQuery('SELECT COUNT (*) from $noteTable');
int result = Sqflite.firstIntValue(x);
return result;
}
// Get the 'Map List' [ List<Map> ] and convert it to 'Note List' [ List<Note> ]
Future<List<Note>> getNoteList() async {
var noteMapList = await getNoteMapList(); // Get 'Map List' from database
int count = noteMapList.length; // Count the number of map entries in db table
List<Note> noteList = List<Note>();
// For loop to create a 'Note List' from a 'Map List'
for (int i = 0; i < count; i++) {
noteList.add(Note.fromMapObject(noteMapList[i]));
}
return noteList;
}
}
While this is the function which it states as not declared
Future<Database> get database async{
if(_database == null){
_database = await initializeDatabase();
}
return _database;
}
Future<Database> initializeDatabase() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'notes.db';
var notesDatabase = await openDatabase(path, version: 1, onCreate: _createDb);
return notesDatabase;
}
I'm doing a simple flutter application with a small Database but when I try to insert data to my table this error appears to me:
Exception has occurred.
NoSuchMethodError (NoSuchMethodError: The method 'insert' was called on null. Receiver: null Tried calling: insert("userTable", _LinkedHashMap len:3))
this is my code:
// database_helper.dart
import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite/sqlite_api.dart';
import 'package:test_sql/models/user.dart';
class DataBaseHelper{
final String tableUser = "userTable" ;
final String columnId = "id" ;
final String columnName = "username" ;
final String columnPassword = "password" ;
static final DataBaseHelper _instance = new DataBaseHelper.internal();
DataBaseHelper.internal();
factory DataBaseHelper() => _instance ;
static Database _db ;
Future<Database> get dbase async{
if(_db !=null){
return _db ;
}
else
{
_db = await initDb() ;
}
}
initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory() ;
String path = join(documentDirectory.path,"mydb.db") ;
var ourDb = await openDatabase(path, version: 1,onCreate: _onCreate);
return ourDb ;
}
void _onCreate(Database db , int version) async {
await db.execute("CREATE TABLE $tableUser($columnId INTEGER PRIMARY KEY , $columnName TEXT,$columnPassword TEXT)");
}
Future<int> saveUser (User user) async{
var dbClient = await dbase ;
await initDb() ;
int result = await dbClient.insert(tableUser, user.toMap(),); // insert(tableUser, user.toMap())
return result ;
}
Future<List> getAllUsers() async {
var dbClient = await dbase ;
var result = await dbClient.rawQuery("SELECT * FROM $tableUser") ;
return result.toList() ;
}
Future<User> getUser(int userId) async {
var dbClient = await dbase ;
var result = await dbClient.rawQuery("SELECT * FROM $tableUser Where $columnId = $userId ") ;
if(result.length==0) return null ;
return new User.fromMap(result.first) ;
}
Future<int> deleteUser(int userId) async{
var dbClient = await dbase ;
return await dbClient.delete(tableUser,where: "$columnId=?",whereArgs: [userId]) ;
}
Future<int> updateUser(User user) async {
var dbClient = await dbase ;
return dbClient.update(tableUser, user.toMap(),where: "$columnId=?",whereArgs: [user.id]) ;
}
Future close() async {
var dbClient = await dbase ;
return dbClient.close() ;
}
}
//user.dart
class User{
String _username ;
String _password ;
int _id ;
User(this._id,this._username,this._password) ;
User.map(dynamic obj ){
this._username = obj['username'] ;
this._password = obj['password'] ;
this._id = obj['id'] ;
}
String get username => _username ;
String get password => _password ;
int get id => _id ;
Map<String,dynamic> toMap() {
var map = new Map<String,dynamic>() ;
map["username"] = _username ;
map["password"] = _password ;
if(_id != null){
map["id"] = _id ;
}
return map ;
}
User.fromMap(Map<String,dynamic>map){
this._username=map["username"] ;
this._password=map["password"] ;
this._id=map["id"] ;
}
}
// main.dart
import 'package:flutter/material.dart';
import 'package:test_sql/database_helper.dart';
import 'package:test_sql/models/user.dart';
void main() async {
var db = new DataBaseHelper() ;
int savedUserId = await db.saveUser(new User(1,"Samir Ben Halima", "Sonia el Ayeb")) ;
print(savedUserId) ;
runApp( MaterialApp(
title: "3atba",
home: MyApp(),
)
);
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(
title: Text("3atba"),
centerTitle: true,
backgroundColor: Colors.green,
),
),
);
}
}
pubspec.yaml
name: test_sql
description: A new Flutter project.
# The following defines the vers[![this is the place of the ERROR][1]][1]ion and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.1.0 <3.0.0"
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: ^0.1.2
sqflite: any
path_provider: any
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
i think the bug was here (this is the fixed code):
if(_db !=null){
return _db ;
}else
{
_db = await initDb() ;
return _db;
}
you just need to return the variable _db after you initialise it
hope it helped