I am trying to retrieve data from firebase database and display it on my UI. This is the code written :
class AllCourses {
String courseName;
String teacher;
String category;
AllCourses(this.courseName, this.teacher, this.category);
}
import 'package:creators_club/firestore/courses.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
class BusinessPage extends StatefulWidget {
#override
_BusinessPageState createState() => _BusinessPageState();
}
class _BusinessPageState extends State<BusinessPage> {
List<AllCourses> coursesList = [];
#override
void initState(){
super.initState();
DatabaseReference referenceAllCourses = FirebaseDatabase.instance.reference().child('AllCourses');
referenceAllCourses.once().then(((AllCoursesSnapshot allCoursesSnapshot){
coursesList.clear();
var keys = allCoursesSnapshot.value.keys;
var values = allCoursesSnapshot.value;
for(var key in keys){
AllCourses allCourses = new AllCourses(
values [key]["courseName"],
values [key]["teacher"],
values [key]["category"],
);
coursesList.add(allCourses);
}
setState(() {
//HERE
});
}));
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),),
title: Text("Creator's Club"),
backgroundColor: Color(0xff2657ce),
elevation: 0,),
body: coursesList.length == 0 ? Center(child: Text("No Data Avail", style: TextStyle(fontSize: 15),)): ListView.builder(
itemCount: coursesList.length,
itemBuilder: (_,index){
return CardUI(coursesList[index].courseName, coursesList[index].teacher, coursesList[index].category);}
)
);
}
}
}
Why isn't the AllCoursesSnapshot being recognized? It says that it is "Type: Null Function(dynamic)".
Here is a picture of the database table in Realtime Database: (https://imgur.com/a/xDZy1SW).
It is not recognized because there is no class called AllCoursesSnapshot. The once() method belongs to the firebase_database plugin, and it returns a Future<DataSnapshot>, therefore you have to do the following:
referenceAllCourses.once().then((DataSnapshot dataSnapshot){
Also replace allCoursesSnapshot with dataSnapshot in the other parts of your code.
Related
I was following a tutorial of sorts and got to a section where we print out what we have in the firestore database. However for some reason my Provider.of seems to be returning null when there is at least one data entry.
home.dart and MemoryList:
class Home extends StatelessWidget {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return StreamProvider<List<Person>>.value (
value: DatabaseService().memories,
initialData:[],
child: Scaffold(
backgroundColor: Colors.lightBlueAccent[50],
appBar: AppBar(
title: Text('Memory Bank'),
backgroundColor: Colors.deepPurple[300],
elevation: 0.0,
actions: <Widget>[
TextButton.icon(
icon: Icon(Icons.person),
label: Text('logout'),
onPressed: ()async{
await _auth.signOut();
},
),//textbutton
],//widget[]
),//appbar
body: MemoryList(),
)//scaffold
);//streamProvider.value
}
}
class MemoryList extends StatefulWidget {
#override
_MemoryListState createState() => _MemoryListState();
}
class _MemoryListState extends State<MemoryList> {
#override
Widget build(BuildContext context) {
final memories = Provider.of<List<Person>>(context);
print("current data:");
print(memories);
if(memories != null){
memories.forEach((element) {
print(element.name);
//print(element.name.events);
//print(element.name.likes);
});
}
return ListView.builder(
itemCount: memories.length,
itemBuilder: (context,index){
return MemoryTile(person: memories[index]);
}
);
}
}
For here the Provider.of<List>(context) returns with nothing.
The stream is:
final CollectionReference memoryCollection = FirebaseFirestore.instance.collection('memories');
Stream<List<Person>> get memories {
Stream<QuerySnapshot> snapshot_stream = memoryCollection.snapshots();
print("getting memories: ");
//print(snapshot_stream.first);
//print(snapshot_stream.first.toString());
return memoryCollection.snapshots().map(_memoryListFromSnapshot);
}
With a simple Person model with just a name:
class Person{
final String name;
Person({required this.name});
}
Any help would be appreciated!
I'm trying to create a chart on a Flutter web app by accessing data from Cloud Firestore.
However, it can't seem to extract and map the details from Firestore.
Firebase console
main.dart
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Home(),
);
}
}
home.dart
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:inglesy/items.dart';
import 'package:charts_flutter/flutter.dart' as charts;
class Home extends StatefulWidget {
#override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
List<charts.Series<Item, String>>? _seriesBarData; //Try (dynamic,String)
List<Item>? myData;
_generateData(myData) {
print("_generateData worked");
_seriesBarData?.add(
charts.Series(
domainFn: (Item item, _) => item.itemstring.toString(),
measureFn: (Item item, _) => item.itemvotes,
id: 'Items',
data: myData,
),
);
}
#override
Widget build(BuildContext context) {
print("returning AppBar/scaffold now");
return Scaffold(
appBar: AppBar(
title: const Text("This is a title."),
foregroundColor: Colors.pink,
),
body: _buildBody(context),
);
}
Widget _buildBody(context) {
print("Doing _buildBody now");
final Stream<QuerySnapshot> _userStream =
FirebaseFirestore.instance.collection("poll").snapshots();
return StreamBuilder<QuerySnapshot>(
stream: _userStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
} else {
List<Item> item = snapshot.data!.docs
.map((DocumentSnapshot document) =>
Item.fromMap(document.data() as Map<String, dynamic>))
.toList();
return _buildChart(context, item);
}
},
);
}
Widget _buildChart(BuildContext context, List<Item> item) {
myData = item;
_generateData(myData);
return Padding(
padding: EdgeInsets.all(8.0),
child: Container(
child: Center(
child: Column(
children: [
Text("This is a text"),
SizedBox(height: 10.0),
Expanded(
child: charts.BarChart(
_seriesBarData!,
animate: true,
animationDuration: const Duration(seconds: 2),
),
)
],
),
),
),
);
}
}
items.dart
class Item {
final String? itemstring;
final int? itemvotes;
Item({this.itemstring, this.itemvotes});
Item.fromMap(Map<String, dynamic> map)
: assert(map['itemstring'] != null),
assert(map['itemvotes'] != null),
itemstring = map['itemstring'],
itemvotes = map['itemvotes'];
#override
String toString() {
return "Item string: $itemstring | Item votes: $itemvotes";
}
}
It shows this error
PS, I've already done the necessary set-up i.e. I've already installed Firebase CLI and have it generated firbase_options.dart
PPS, I have also already set up Firebase (anonymous) authentication and it works with no errors. But for now, I'm not using it and I'm automatically running home.dart to focus on the Firebase database aspect.
Why don’t you try making the Item.fromMap method a regular factory method like:
factory Item.fromMap(Map<String, dynamic> map) {
return Item(
itemstring = map['itemstring'] ?? '',
itemvotes = map['itemvotes'] ?? ''
);
}
Patients model dart file;
import 'package:flutter/material.dart';
class Patients {
String patientId;
String nurseId;
String username;
DateTime date;
int age;
List<String> diseases;
//final fotograf olacak
Patients({#required this.patientId,this.nurseId,this.date,this.username,this.age,this.diseases});
factory Patients.fromJson(Map<String, dynamic> json){
return Patients(
patientId: json["patientId"],
nurseId: json["nurseId"],
username: json["username"],
date: json["date"],
age: json["age"],
diseases: json["diseases"],
);
}
Map<String,dynamic> toMap(){
return {
"patientId": patientId,
"nurseId" : nurseId,
"username" : username,
"date" : date,
"age" : age,
"diseases" : diseases,
};
}
}
PatientsProvider dart file;
import 'package:flutter/material.dart';
import 'package:imlearningfirebase/model/patients.dart';
import 'package:uuid/uuid.dart';
import 'package:imlearningfirebase/services/fireStoreService.dart';
class PatientsProvider with ChangeNotifier{
final fireStoreService = FireStoreService();
String _patientId;
String _nurseId;
DateTime _date;
String _username;
int _age;
List<String> _diseases;
var uuid = Uuid();
///Getters
String get username =>_username;
int get age => _age;
List<String> get diseases => _diseases;
DateTime get date => _date;
Stream<List<Patients>> get getPatients => fireStoreService.getEntries();
savePatient(int agee,String usernamee,List<String> diseasess){
if(_nurseId == null){
///add
var newPatient = Patients(patientId: uuid.v1(),nurseId:fireStoreService.getCurrentUserId().toString(),date:DateTime.now(),username: usernamee,age: agee,diseases: diseasess);
print(newPatient.username);
fireStoreService.setPatients(newPatient);
}else{
var updatedPatients = Patients(patientId: uuid.v1(),nurseId:fireStoreService.getCurrentUserId().toString(),date:DateTime.now(),username: usernamee,age: agee,diseases: diseasess);
fireStoreService.setPatients(updatedPatients);
}
}
}
FireStoreService dart file;
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
/// Local Importlar
import '../model/patients.dart';
class FireStoreService{
FirebaseFirestore _db = FirebaseFirestore.instance;
final FirebaseAuth auth = FirebaseAuth.instance;
///Get Entries
Stream<List<Patients>> getEntries(){
return _db
.collection("patients")
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => Patients.fromJson(doc.data()))
.toList());
}}
Home screen;
import 'package:flutter/material.dart';
import 'package:imlearningfirebase/provider/patienstProvider.dart';
import 'package:provider/provider.dart';
class HomePage extends StatelessWidget{
#override
Widget build(BuildContext context) {
final patientsProvider = Provider.of<PatientsProvider>(context);
return Scaffold(
appBar: AppBar(
title: Text("Patients"),
),
floatingActionButton: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 50.0),
child: FloatingActionButton(
onPressed: () async {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddPatient()),
);
},
child: Icon(
Icons.add,
color: Colors.blueAccent,
),
backgroundColor: Colors.green,
),
),
body:StreamBuilder<List<Patients>>(
stream: patientsProvider.getPatients,
builder: (context,snapshot){
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context,index){
return ListTile(
trailing:
Icon(Icons.edit, color: Theme.of(context).accentColor),
title: Text('${DateTime.now()}'
),
);
}
);
}
)
);
}
}
I am trying to create a system where a person has to register and register another person. I created a model so that the registered person creates the profile of the other person. The name of this model is patients. I use the provider package to access patients functions. I have created a function named take patients in Firestore and put it in the patient provider. Finally, I call this on the Home page. but the length came null. I can not see the error I would be glad if you help.
I didn't use your FireStoreService() class. This might be a bit messy but it worked for me. let me know if it works.
Try this:
class PatientsProvider with ChangeNotifier {
...
List<Patients> _patients = [];
// ///Getters
...
// Stream<List<Patients>> get getPatients => fireStoreService.getEntries();
List<Patients> get getPatients => _patients;
FirebaseFirestore _fs = FirebaseFirestore.instance;
StreamSubscription<QuerySnapshot> _stream;
PatientsProvider() {
_stream = _fs.collection('patients').snapshots().listen((snapshot) {
_patients = [];
snapshot.docs.forEach((queryDocumentSnapshot) {
_patients.add(Patients.fromJson(queryDocumentSnapshot.data()));
});
notifyListeners();
});
}
#override
void dispose() {
super.dispose();
_stream.cancel();
}
// savePatient(int agee, String usernamee, List<String> diseasess) {
...
// }
}
Then instead if creating a streambuilder, the provider will update the list when the data changes:
#override
Widget build(BuildContext context) {
PatientsProvider _provider = Provider.of<PatientsProvider >(context);
return Scaffold(
body: ListView.builder(
itemCount: _provider.getPatients.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
trailing: Icon(Icons.edit, color: Theme.of(context).accentColor),
title: Text('${...}'),
);
},
),
);
}
To get more information on the listener see this documentation:
https://firebase.google.com/docs/firestore/query-data/listen
I tried this tutorial
https://www.youtube.com/watch?v=ZiagJJTqnZQ
but my data didn't show, the length is still showing 0
This is my firebase https://i.imgur.com/D6kBpp8.png
Code
questions.dart
class Questions {
String question, questioner, status;
Questions(this.question, this.questioner, this.status);
}
timeline.dart
import 'package:flutter/material.dart';
import 'questions.dart';
import 'package:firebase_database/firebase_database.dart';
class TimeLine extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _TimeLineState();
}
}
class _TimeLineState extends State<TimeLine> {
final primaryColor = const Color(0xFF006FB9);
final bgColor = const Color(0xFFFEFEFE);
List<Questions> questionsList = [];
#override
void initState() {
super.initState();
DatabaseReference questionsRef = FirebaseDatabase.instance.reference().child("Questions");
questionsRef.once().then((DataSnapshot snap)
{
var KEYS = snap.value.keys;
var DATA = snap.value;
questionsList.clear();
for(var individualKey in KEYS) {
Questions questi = new Questions(
DATA[individualKey]['question'],
DATA[individualKey]['questioner'],
DATA[individualKey]['status'],
);
questionsList.add(questi);
}
setState(() {
print('Length : $questionsList.length');
});
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 1,
title: Text('Discover'),
backgroundColor: primaryColor,
),
backgroundColor: bgColor,
body: Container(
child: Text(
questionsList.length.toString()
)
/*questionsList.length == 0 ? new Text("No Blog Post Available") : new ListView.builder(
itemCount: questionsList.length,
itemBuilder: (_, index) {
return QuestionsGrid(questionsList[index].question, questionsList[index].questioner, questionsList[index].status);
}
),*/
),
);
}
Widget QuestionsGrid(String question, String questioner, String status) {
return new Container(
height: 1000,
width: 1000,
child: Text(
question
),
);
}
}
Your code is perfect but you have to change in to your firebase code line like
DatabaseReference questionsRef = FirebaseDatabase.instance.reference().child("questions");
Instand of
DatabaseReference questionsRef = FirebaseDatabase.instance.reference().child("Questions");
Thanks
I'm working on a Flutter project and using Sqflite database. I've managed to save data in db. Now I am trying to get list of all records from database based on table name and display them in "ListView.builder".
database_helper.dart
Future<List> getAllRecords(String dbTable) async {
var dbClient = await db;
var result = await dbClient.rawQuery("SELECT * FROM $dbTable");
return result.toList();
}
employees_list.dart
import 'package:flutter/material.dart';
import 'package:flutter_with_db_single_helper/helpers/database_helper.dart';
var db = new DatabaseHelper();
Future<List> _users = db.getAllRecords("tabEmployee"); // CALLS FUTURE
class EmployeesListScreen extends StatefulWidget {
#override
_EmployeesListScreenState createState() => _EmployeesListScreenState();
}
class _EmployeesListScreenState extends State<EmployeesListScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('List Of Employees'),
),
body: ListView.builder(
// itemCount: _users.length,
itemBuilder: (_, int position) {
return Card(
child: ListTile(
title:
Text("Employee Name: "), // EMPLOYEE NAME TO BE DISPLAYED HERE
),
);
},
),
);
}
}
Where did I go wrong? What can I do to display all my db table records in list?
You could use a FutureBuilder to get and display your data :
class _EmployeesListScreenState extends State<EmployeesListScreen> {
var db = new DatabaseHelper(); // CALLS FUTURE
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('List Of Employees'),
),
body: FutureBuilder<List>(
future: db.getAllRecords("tabEmployee"),
initialData: List(),
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, int position) {
final item = snapshot.data[position];
//get your item data here ...
return Card(
child: ListTile(
title: Text(
"Employee Name: " + snapshot.data[position].row[1]),
),
);
},
)
: Center(
child: CircularProgressIndicator(),
);
},
),
);
}
}
This might not be correct code, since I've not tested this, but this is how list view builder works and try using async await. Cleans up code quite a bit!
import 'package:flutter/material.dart';
import 'package:flutter_with_db_single_helper/helpers/database_helper.dart'
class EmployeesListScreen extends StatefulWidget {
#override
_EmployeesListScreenState createState() => _EmployeesListScreenState();
}
class _EmployeesListScreenState extends State<EmployeesListScreen> {
List<String> _records;
#override
initState(){
super.initState();
}
Future<void> _getRecords() async {
var res = await db.getAllRecords("tabEmployee");
setState((){
_records = res;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('List Of Employees'),
),
body: _records==null ? Container():ListView.builder(
itemCount: _records.length,
itemBuilder: (_, int position) {
return Card(
child: ListTile(
title:
Text("Employee Name: ", _records[position]),
),
);
},
),
);
}
}
Or you can use a future builder, as the other answer shows. :)