Searching in Database - Sqlite Flutter - database

i miss something in my code, i use an existing database (sqlite) in my mobile app, and i want to add a search bar to it, everythings works fine, but the result in the emulator is like this :
{content: name1}
{content: name2}
{content: name3}
i want just the names,
thank you for your help !
This is my code :
String text;
List course;
void _query (text) async {
Database db = await DatabaseHelper.instance.database;
List<Map> result = await db.rawQuery("SELECT content FROM table WHERE content LIKE '%${text}%'");
setState(() {
result.forEach((element) {
print(element);
course = result;
});
});
}
body:Column(
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.search,
color: Colors.grey,
),
SizedBox(
width: 20,
),
Container(
width: MediaQuery.of(context).size.width - 100.0,
child: TextField(
decoration: InputDecoration(
hintText: search ... ,
),
onChanged: (String text) async {
_query(text);
},
),
),
],
),
),
Expanded(
child: ListView.builder(
padding: const EdgeInsets.all(14.0),
itemBuilder: (context, index) {
return Column(
children: [
Divider(
height: 20,
),
Material(
color: Colors.grey,
child: ListTile(
title: Text(
course == null
? 'loading'
: '${course[index]}',
style: TextStyle(
color: Colors.black),
),
),
)
],
);
}
),
),
],
),

You can try this
result.forEach((element) {
print(element);
print(element['content']);
course = result;
});

You can access elements of a Map with the [] operator. You can use the map function of List to modify the list that you're displaying to be only the actual names.
void _query (text) async {
Database db = await DatabaseHelper.instance.database;
List<Map> result = await db.rawQuery("SELECT content FROM table WHERE content LIKE '%${text}%'");
setState(() {
course = result.map<String>((element) {
return element['content'];
}).toList();
});
}

Related

firestore.set does not save the data in firestore. cannot get a field on a DocumentSnapshotPlatform which does not exist

I use firestore to save the data. So, I use 'set'method. but It can't save the data. I get the error cannot get a field on a DocumentSnapshotPlatform which does not exist. How can I solve this error?
this my code. first code is input the title and content code. '''
class WritePage extends StatefulWidget {
#override
_WritePageState createState() => _WritePageState();
}
class _WritePageState extends State<WritePage> {
DataBase dataBase = new DataBase();
String title = ' '; //제목
String content = ' '; //내용
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("글쓰기"),
),
body: Center(
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(20, 20, 20, 5),
child: TextField(
onChanged: (String text) {
if(text != null) {
title = text;
}else{title = 'null';}
},
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
hintText: '제목을 적어주세요',
border: OutlineInputBorder(),
labelText: "제목을 입력하세요.",
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(20, 20, 20, 5),
child: TextField(
onChanged: (String text) {
if(text != null) {
content = text;
}else{content = 'null';}
},
keyboardType: TextInputType.multiline,
maxLines: 20,
decoration: InputDecoration(
hintText: '내용을 적어주세요',
border: OutlineInputBorder(),
labelText: "내용을 입력하세요.",
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(20, 5, 20, 5),
child: SizedBox(
height: 50,
width: 400,
child: TextButton(
onPressed: () async {
DataBase dataBase = new DataBase();
var now = DateTime.now();
await dataBase.add(title, content, '$now');
Navigator.pop(context);
},
child: Text(
'글쓰기',
style: TextStyle(color: Colors.black),
),
style: TextButton.styleFrom(primary: Colors.blue),
),
),
),
],
)
],
),
),
);
}
}
''''
this is my code2. this code is to save the data in firestore.
but it does not work.
class DataBase {
FirebaseFirestore firestore = FirebaseFirestore.instance;
String collection = '게시판';
add(String title, String content, String date_time) {
firestore
.collection('카운트')
.doc('카운트')
.get().then((DocumentSnapshot ds) {
firestore.collection(collection).doc('${ds['카운트']!}').set(
{'제목': title, '내용': content,
'날짜': date_time, 'id': ds['카운트']!});
int id = ds['카운트']! + 1;
cntupdate(id);
});
}
void cntupdate(int _id) {
firestore.collection('카운트').doc('카운트').update({'id': _id,
'카운트': _id});
}

Flutter Images in a List (Flutter)

so I want to have a List/Array that contains images and where each image has his own title.
The image and the title should be shown in two different buttons and the title should change when I tap on the image.
I already could solve the first two points (to show in different places and that the title changes)
But I don't know how to add images to my List, could you help me?
In addition to that, the List should be randomized, but the title should always "stay" with his image.
I hope you understand what I want and thank you for your help.
class Sachen {
String title;
String image;
Sachen(this.title, this.image);
}
final List<Sachen> infoBank = [
Sachen("Chips", "images/snack1.png",),
Sachen("Erdnussflips", "images/snack2.png",),
];
int bankNumber = Random().nextInt(2) +1;
#override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
Card(
margin: EdgeInsets.fromLTRB(50, 35, 50, 0),
elevation: 8,
color: Color(0xFF4caf50),
child: SizedBox(
height: 80,
width: 150,
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 18),
child: GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Rezept('Rezept'),
),
);
},
child: SizedBox(
height: 125,
width: 150,
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 18),
child: Text(
infoBank[bankNumber].title,
style: GoogleFonts.rubik(
fontSize: 20,
color: Colors.white,
),
),
),
),
),
),
),
),
),
),
Row(
children: [
Expanded(
child: TextButton(
onPressed: () {
setState(() {
bankNumber++;
});
changeDiceNumber();
print('LeftDiceNumber = $DiceNumber');
},
child: Container(
margin: EdgeInsets.fromLTRB(10, 20, 10, 20),
decoration: BoxDecoration(
border: Border.all(
width: 2,
color: Colors.grey.shade700,
),
),
height: 350,
width: 350,
child: Image.asset('images/snack$DiceNumber.png',
fit: BoxFit.cover,
),
),
),
),
],
),
],
),
);
}
}
have you tried using Flutter's ListViewBuilder?
Like alread said ListView().builder will be a good usage.
Instead of building the widget you can just use ListTile or Card there you already have trailing, leading, and title for the positioning of your images.
Althou i would change the class Sachen with a final Icon or IconData to directly add it to your List. In The Constructor please use required for the parameters its for better reading and don't do mistakes
This is my first idea to use this
class Sachen {
final String title;
final String image;
Sachen({
required this.title,
required this.image,
});
}
final List<Sachen> liste = [
Sachen(title: "title", image: "name"),
Sachen(title: "title1", image: "name1"),
];
return ListView.builder(itemBuilder: (context, index) {
return ListTile(
leading: Image.asset(liste[index].image),
title: Text(liste[index].title),
onTap: (){
//Do On Tap
//remember to use SetState when you want to rebuild some changes
},
);
});
Other Idea maybe a little bit better:
class Sachen {
final String title;
final Image image;
Sachen({
required this.title,
required this.image,
});
}
final List<Sachen> liste = [
Sachen(title: "title", image: Image.asset("name")),
Sachen(title: "title1", image: Image.asset("name1")),
];
#override
Widget build(BuildContext context) {
return ListView.builder(itemBuilder: (context, index) {
return ListTile(
leading: liste[index].image,
title: Text(liste[index].title),
onTap: () {
//Do On Tap
//remember to use SetState when you want to rebuild some changes
},
);
});
}

How to separate data into different databases?

I have a database where I want to add and store information about a particular destination or activity. In the insert information page, I have a section where user can select either destination or activity as its category. However, all these are being stored into one database but I want to have different ones for each.
This is the current code that adds them into one database:
void addDestOrAct(String name, String details, var category) {
String key = destdatabaseref
.child('Database')
.child('DestinationsandActivities')
.push()
.key;
destdatabaseref
.child('Database')
.child('DestinationsandActivities')
.child(name)
.set({
'id': key,
'name': name,
'description': details,
'category': category
});
nameController.clear();
descriptionController.clear();
Fluttertoast.showToast(
timeInSecForIosWeb: 4,
gravity: ToastGravity.CENTER,
msg: "It has been added!");
Navigator.pop(context);
}
I want to put something like if (category = 'Activity') then add into destdatabaseref.child('Database').child('Activities') instead of .child('DestinationsandActivities').
Selection of category and inserting data code:
Padding(
padding: const EdgeInsets.only(right: 290),
child: Text(
'Category :',
style: TextStyle(fontSize: 15, color: Colors.grey),
),
),
SizedBox(height: 13),
Container(
height: 40,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
_categoryType('Destination'),
SizedBox(width: 10),
_categoryType('Activity'),
],
),
),
SizedBox(height: 40),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Color(0xFF3d5a89),
padding:
EdgeInsets.symmetric(horizontal: 45, vertical: 10),
textStyle: TextStyle(
fontWeight: FontWeight.w500,
color: Colors.white,
fontSize: 15)),
onPressed: () {
if (_formKey.currentState!.validate()) {
if (nameController.text.isNotEmpty &&
descriptionController.text.isNotEmpty) {
addDestOrAct(nameController.text,
descriptionController.text, _categorySelected);
} else
return null;
}
},
child: Text('Add')
)
Category type widget code:
Widget _categoryType(String title) {
return InkWell(
child: Container(
height: 70,
width: 120,
decoration: BoxDecoration(
color: _categorySelected == title
? Color(0xFF5a893d)
: Color(0xFF3d5a89),
borderRadius: BorderRadius.circular(15),
),
child: Center(
child: Text(
title,
style: TextStyle(fontSize: 13, color: Colors.white),
),
),
),
onTap: () {
setState(() {
_categorySelected = title;
});
},
);
}
How can I can add information into different databases based on category? I have the database 'DestinationsandActivities' for now but would really prefer it to be 'Destinations' and 'Activities'.
Thanks to #Frank van Puffelen, it was simply :
if (category == 'Activity') {
//code here
});
}
if (category == 'Destination') {
//code here
});
}

How to fetch data from cloud firestore in flutter?

I want to fetch contact details like phone number, email address, website url & also social media urls from firestore in flutter. I done coding to show contact details directly in-app but I need to get data from firestore because it will be good for me if suppose i need to change contact details in future.
My coding
import 'package:cloud_firestore/cloud_firestore.dart';
class AboutPage extends StatelessWidget {
const AboutPage({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: LightColor.white,
appBar: CustomAppBar(
isBackButton: true,
title: customTitleText(
'Contact us',
),
),
body: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
HeaderWidget(
'Feel free to contact us',
secondHeader: true,
),
SettingRowWidget(
"Phone",
vPadding: 0,
showDivider: false,
onPressed: () {
Utility.launchURL(///i want to display this url from firestore///
"tel:+918889999888");
},
),
HeaderWidget('Social media'),
SettingRowWidget("Facebook", showDivider: true, onPressed: () {
Utility.launchURL( ///i want to display this url from firestore///
"https://facebook.com/ecways");
}),
HeaderWidget('Website'),
SettingRowWidget("Open website", showDivider: true, onPressed: () {
Utility.launchURL( ///i want to display this url from firestore///
"https://facebook.com/");
}),
],
),
);
}
}
I created firestore database with collection name "my_contact" and document name "details" and also i created field for phone, email, website and extra. Now i just want to know how to display that collection in my app with my coding.
First of all you have to change your firestore database as below
There should be array called contacts and inside that there should be 3 maps according to your data.
Then create a list in your screen class.
List contacts;
Then create a function to retrieve data from firestore.
Future<List> fetchAllContact() async {
List contactList = [];
DocumentSnapshot documentSnapshot =
await firestore.collection('my_contact').doc('details').get();
contactList = documentSnapshot.data()['contacts'];
return contactList;
}
Then call this function inside initState function.
#override
void initState() {
super.initState();
fetchAllContact().then((List list) {
setState(() {
contacts = list;
});
});
}
Finally replace your listView as a listViewBuilder.
Container(
child: ListView.builder(
padding: EdgeInsets.all(10),
itemCount: contacts.length,
itemBuilder: (context, index) {
return CustomTile(
mini: false,
onTap: () {},
title: Text(
contacts[index]['headerTitle'] != null
? contacts[index]['headerTitle']
: '',
style: TextStyle(
color: Colors.white,
fontFamily: "Arial",
fontSize: 19),
),
subtitle: Text(
contacts[index]['value'] != null
? contacts[index]['value']
: '',
style: TextStyle(
color: UniversalVariables.greyColor,
fontSize: 14,
),
),
leading: Container(
constraints:
BoxConstraints(maxHeight: 60, maxWidth: 60),
child: Stack(
children: <Widget>[
CircleAvatar(
maxRadius: 30,
backgroundColor: Colors.grey,
backgroundImage: NetworkImage(
"https://avatars.githubusercontent.com/u/49371842?v=4"),
),
Align(
alignment: Alignment.bottomRight,
child: Container(
height: 13,
width: 13,
decoration: BoxDecoration(
shape: BoxShape.circle,
color:
UniversalVariables.onlineDotColor,
border: Border.all(
color:
UniversalVariables.blackColor,
width: 2)),
),
)
],
),
),
);
}
),
)
This is how I did it. Thanks...
flutterfire now have a good walk through for that. Please refer to this section for fetching data from firestore https://firebase.flutter.dev/docs/firestore/usage/#collections--documents

How to use StreamBuilder to show a list of data from firestore document

I want to be able to create a list from an array inside a document in firestore database.
My database is like so:
I want to be able to create a streamBuilder grid from the urls inside the videosUrl array.
I tried a lot of things, but I guess that the best way is something like this one:
StreamBuilder <List<DocumentSnapshot>>(
stream: Firestore.instance
.collection('events')
.document('-LeH4rspnPTpeTLdt8hs')
.collection('participants')
.document('-LeL_TSfFDfqKgm-Io9T')
.snapshots().asyncMap((snap) async {
List<String> videosUrlArray = snap.data['videosUrl'];
var videoUrlList = <DocumentSnapshot>[];
for (var videoUrlPath in videosUrlArray) {
videoUrlList.add(await Firestore.instance.document(videoUrlPath).get());
}
print(videoUrlList);
return videoUrlList;
}),
builder: (BuildContext context, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting: return _showLoading();
default:
return new GridView(
reverse: false,
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
children: snapshot.data.map((DocumentSnapshot document) {
return Text('${snapshot.data}');
}).toList(),
);
}
},
)
but still I can't access the data!
I resolve this issue with the code below:
Widget buildGridFilesToExport(){
return new StreamBuilder(
stream: Firestore.instance
.collection('users')
.document(dataUserGlobal.userAdminId)
.collection('events')
.document(dataUserGlobal.eventId)
.snapshots(),
builder: (context, snapshot) {
print(snapshot);
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting: return new Text('Loading...');
default:
List videosList = snapshot.data['thumbnailsUrl'];
return
videosList != null ?
new GridView.count(
crossAxisCount: 2,
childAspectRatio: 1,
children: List.generate(snapshot.data['thumbnailsUrl'].length, (index) {
return Container(
padding: EdgeInsets.all(5.0),
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 2.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
image: DecorationImage(
image: NetworkImage(snapshot.data['thumbnailsUrl'][index]),
fit: BoxFit.cover,
),
),
),
],
)
);
}),
)
:
Center(
child: Container(
width: 300,
child: Text(
'Ancora nessun video!\nVai nella cartella amici e accetta i loro video!',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'acumin-pro',
fontSize: 22,
),
),
)
);
}
},
);
}

Resources