I’m using some sqflite to do a query on a database, and extract a specific name of a table, for example: I have 3 names, Roberto, Ricardo and Andres, and I want to obtain only the name of Roberto, so this is what im doing:
loginLogic() async {
var X = 'Roberto';
final db = await database;
List<Map> result = await db.rawQuery('SELECT * FROM Usuario WHERE username=?', [X]);
So now, I want to compare this result with another one to do an "if" function, just like this:
if(result==X){
return 1;
} else {
return 0;
}
But this is what flutter says:
List<Map<dynamic, dynamic>> result
Equality operator '==' invocation with references of unrelated
And the Debug console:
type 'Future<dynamic>' is not a subtype of type 'int'
So I need a way to compare the value that results from the list of users with the string with the variable I declarated 'X'.
Try using the reference of this problem
This is what I’ve tried:
loginLogicpar() async {
var X = 'Giova';
final db = await database;
final result = await db.rawQuery('SELECT * FROM Usuario WHERE username=?', [X]);
return result;
}
loginLogic() async {
var X = 'Giova';
final user = await loginLogicpar();
if(user==X){
return 1;
}
return 0;
}
And returns the exact same result: type 'Future' is not a subtype of type 'int'
Added the code so you can replicate it, just be sure you have sqflite on your depenencies.
It was a hell of a road, but i made it with the help of you all, but the final piece was #mutantkeyboard, what i was getting was a list of the different elements from the table of Sqflite, but after converting it with a variable and the .first function i get to transform it to another variables! here's what i made:
loginLogic() async {
final db = await database;
var table = await db.rawQuery("SELECT MAX(id)+1 as id FROM Usuario");
int id = table.last["id"];
for(var i=1; i<id; i++){
var result = await db.rawQuery('SELECT username FROM Usuario WHERE id=?', [i]);
String Y = result.first["username"];
if(Y=='Roberto'){
return 1;
}
}
return 0;
}
if you want to compare it with another variable outside, for example, an auth for a local-login (that's what i was doing, just for educational purpose, i'll NEVER suggest you to put your usernames and passwords inside your local software) and compare the textfield.text with the table, then you can modify the code to something like this:
loginLogic(String field) async {
final db = await database;
var table = await db.rawQuery("SELECT MAX(id)+1 as id FROM Usuario");
int id = table.last["id"];
for(var i=1; i<id; i++){
var result = await db.rawQuery('SELECT username FROM Usuario WHERE id=?', [i]);
String Y = result.first["username"];
if(Y==field){
return 1;
}
}
return 0;
}
Related
Firestore with Dart requires query operators to be passed as objects.
Docs: https://firebase.google.com/docs/firestore/query-data/queries
Ex Dart:
.where("key", isEqualTo: value)
Ex Go:
.where("key", "==", value).
In the case of go, passing a string "==" as the query operator is pretty straight forward.
For dart, i am trying to figure out how to store isEqualTo: as a variable, to then pass into the function.
Ok here is my code. Any help is really appreciated thank you!
Here is the DataModel
class FirestoreQueryModel extends Equatable {
//Variables
final String property;
final FirestoreOperatorEnum operator;
// This is the value where i want to store the list of operators
final dynamic value;
}
Here is the current repository
class CustomerRepository{
late Query golbalQuery
Stream <List<CustomerModel>> dynmamicCollectonStream(List<FirestoreQueryModel> queryList,) { //If query list is null, do not apply where clause
if (queryList.isEmpty) { return collectionRef().snapshots().map((doc) {var returnedList = doc.docs; var mappedList = returnedList.map((doc) => CustomerModel.fromDocument(doc)).toList();
return mappedList;
});
} else {var count = queryList.length; CollectionReference cRef = collectionRef();
for (var i = 0; i < count; i++) { golbalQuery = cRef.where(queryList[i].property, isEqualTo: queryList[i].value); }
var list = golbalQuery.snapshots().map((doc) { var returnedList = doc.docs; var mappedList = returnedList.map((doc) =\> CustomerModel.fromDocument(doc)).toList(); return mappedList; }); return list; } }}
In the for loop, where we convert the data model to a where clause I currently have hardcoded isEqualTo:
The goal is to convert
for (var i = 0; i < count; i++) { golbalQuery = cRef.where(queryList[i].property, isEqualTo: queryList[i].value); }
to
for (var i = 0; i < count; i++) { golbalQuery = cRef.where(queryList[i].property, qyeryList[i].operator, queryList[i].value); }
I use firebase firestore to store multiple documents with auto-generated IDs. In my code I generate a random ID and then query the database with "isGreaterThanOrEqualTo: _randomIndex" to read 3 random documents. My issue is: My database is not very big yet. When I use this approach, I sometimes get 0, only 1 or only 2 documents back although I iterate through it 3 times to get 3 documents. I think the reason is because of the limited amount of data there is sometimes no "greaterThanOrEqualTo" ID in my database so I get nothing back.
How can I enhance my code to get always 3 documents back? Is there a way to change the "where query" to
.where('id', isGreaterThanOrEqualTo OR isLessThanOrEqualTo: _randomIndex
My whole Code:
String getRandomGeneratedId() {
const int AUTO_ID_LENGTH = 20;
const String AUTO_ID_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const int maxRandom = AUTO_ID_ALPHABET.length;
final Random randomGen = Random();
String id = '';
for (int i = 0; i < AUTO_ID_LENGTH; i++) {
id = id + AUTO_ID_ALPHABET[randomGen.nextInt(maxRandom)];
print('RandomID is $id');
}
return id;
}
Future<List> getData() async {
List<Recipe> dataList = [];
CollectionReference myRef = FirebaseFirestore.instance.collection('recipes');
// Retrieves 3 random data in a loop
for (int i = 0; i < 3; i++) {
// generate a random index based on the list length
// and use it to retrieve the element
String _randomIndex = getRandomGeneratedId();
print('RandomIndex is $_randomIndex');
QuerySnapshot querySnapshot = await myRef
.where('id', isGreaterThanOrEqualTo: _randomIndex) // CHANGE THIS PART?
.orderBy('id', descending: false)
.limit(1)
.get();
print('QUERYSNAP is $querySnapshot');
dataList.addAll(querySnapshot.docs.map((d)=> Recipe.fromJson(d.data() as Map<String, dynamic>)));
So when I get some string data from database I'm using this method
var res = "";
Future<void> cetak(String query) async {
var req = await SqlConn.readData(query);
setState(() {
res = req;
});
}
then im using method cetak() like this
cetak("SELECT CUST_NAME FROM ts_custxm WHERE CUST_CODE = '$custCode'");
But when im trying to display the res using Text(res)
it show [{"CUST_NAME":"MY NAME"}]
any idea how to make res only show MY NAME without show its column name?
You first need to convert by jsonDecode() or json.decode():
var req = jsonDecode(req)
setState(() {
res = req;
});
and then access to your data by:
res[0]["CUST_NAME"].toString()
You are getting result of a query in res variable. As a result of a query is an array of objects.
in your case : [{"CUST_NAME":"MY NAME"}]
so get MY NAME you should use res[0]["CUST_NAME"].toString().
Hope this will help!
I am currently successfully able to insert values into the system, however, I want to be able to display the inserted values in my console.
How do I print the inserted values in my console? I tried doing so and I was only able to get the "id" of the inserted value. I'm not sure how to print the rest of the values in the table.
Here's my insert code:
// Insert Operation: Insert a Note object to database
Future<int> insertNote(Note note) async {
//getting db reference
Database db = await database;
//running the insert command
//our data from note is converted to map object
var result = await db.insert(noteTable, note.toMap());
if (kDebugMode) {
print('Note data inserted successfully: $result');
}
return result;
}
Here's the code I used to convert the Note object into a Map object
// Convert a Note object into a Map object
Map<String, dynamic> toMap() {
var map = <String,dynamic>{};
if (id != null) {
map['id'] = _id;
}
map['title'] = _title;
map['description'] = _description;
map['priority'] = _priority;
map['color'] = _color;
map['date'] = _date;
return map;
}
This is the result on my console:
When you insert row in database you will only get row id in return.
So if you want to print recent data then you have to make a query to your database with id or you can also print all the data available.
For table
db.query("table_name);
or
db.rawQuery('SELECT * FROM "table"');
For specific id
db.query("table_name",where: '$rowId = ?', whereArgs: [id]);
or
db.rawQuery('SELECT * FROM "table" WHERE $rowId = $id');
For more info check : https://pub.dev/packages/sqflite
I have Flutter + Firestore app with a perfomance problem: large database query execution time (about a 5 sec.). I have a small database size, I think that if it increases, the query execution speed will be even greater. How can I improve application performance?
import 'package:carstat/models/entry.dart';
import 'package:carstat/models/operation.dart';
import 'package:carstat/services/data_service.dart';
class DashboardService {
DataService dataService = DataService();
getMarkers(List<Entry> entries, String carId) async {
var _markers = [];
for (int i = 0; i < entries.length; i++) {
List<Operation> _operations = [];
_operations =
await dataService.getEntryOperations(entries[i].entryId, carId);
_markers.add({'entry': entries[i], 'operations': _operations});
}
return _markers;
}
}
My data structure for example:
.document(docId)
.collection('cars')
.document(carId)
.collection('entries')
.document(entryId)
.collection('operations')
.document();
DataService code:
getEntryOperations(String entryId, String carId) async {
List<Operation> _operations = [];
Future<QuerySnapshot> _userDoc =
fs.where('userId', isEqualTo: _userId).getDocuments();
await _userDoc.then((res) {
docId = res.documents[0].documentID;
});
Future<QuerySnapshot> _entryOperations = fs
.document(docId)
.collection('cars')
.document(carId)
.collection('entries')
.document(entryId)
.collection('operations')
.getDocuments();
await _entryOperations.then((val) {
for (int i = 0; i < val.documents.length; i++) {
var _operation = Operation();
_operation.entryId = entryId;
_operation.operationNote = val.documents[i].data['operationNote'];
_operation.operationDate =
val.documents[i].data['operationDate'].toDate();
_operation.operationMileage = val.documents[i].data['operationMileage'];
_operation.operationPartName =
val.documents[i].data['operationPartName'];
_operation.operationPrice = val.documents[i].data['operationPrice'];
_operation.partPrice = val.documents[i]['partPrice'];
_operation.operationId = val.documents[i]['operationId'];
_operations.add(_operation);
}
});
return _operations;
}
The query you're showing is unconditionally getting all of the documents in a specific subcollection. Of course, that will take more time as the collection grows. There is no secret trick or special flag to pass to make this query happen any faster.
In fact, there is not much you can do about this at all, other than to limit the size of the collection, or limit the number of documents in the query. You might also want to reconsider your database structure to reduce the number of documents you're fetching.
My answer, much faster
class DashboardService {
DataService dataService = DataService();
getMarkers(List<Entry> entries, String carId) async {
var _marker = []; // коллекция списков операторов для каждого регламента ТО
final opsForEntries = await Future.wait(
entries.map((value) {
return dataService.getEntryOperations(value.entryId, carId);
})
);
for(int i = 0; i < entries.length; i++) {
_marker.add(
{
'entry': entries[i],
'operations': opsForEntries[i]
}
);
}
return _marker;
}
}